🦙
🦙
Suave.IO vdir to run choose routes relative to a path
let vdir (s : String) choose_list (ctx : HttpContext) =
if ctx.request.url.StartsWith(s)
then
let us =
if ctx.user_state.ContainsKey("original_url")
then ctx.user_state
else ctx.user_state.Add("original_url", ctx.request.url)
let new_req = { ctx with request={ctx.request with url=ctx.request.url.Substring(s.Length)} ; user_state = us } in
choose choose_list new_req
else None
let subapp =
vdir "/sub" [
url "/abc" >>= OK "subapp abc route"
warbler(fun {request=req ; user_state=us} -> OK ( sprintf "subapp - url %s - original url %A" req.url us))
]
Now when subapp is loaded inside an application’s choose chain, if /sub/xyz is visited, the browser will print:
subapp - url /xyz - original url map [(“original_url”, “/sub/xyz”)]
Is this an abuse of the user_state list maintained by Suave?
As an alternative, we can define the vdir function to take a WebPart:
let vdir (s : String) (app : WebPart) (ctx : HttpContext) =
if ctx.request.url.StartsWith(s)
then
let us =
if ctx.user_state.ContainsKey("original_url")
then ctx.user_state
else ctx.user_state.Add("original_url", ctx.request.url)
let new_req = { ctx with request={ctx.request with url=ctx.request.url.Substring(s.Length)} ; user_state = us } in
app new_req
else None
let subapp =
vdir "/sub" <| choose [
url "/abc" >>= OK "def"
warbler(fun {request=req ; user_state=us} -> OK ( sprintf "subapp with choose - url %s - original url %A" req.url us))
]