-
Notifications
You must be signed in to change notification settings - Fork 196
Description
As a newcomer to Suave, I've been working to move past copying and pasting examples I come across, and I've started building an application from scratch. During this process, I attempted to do something like this:
let app =
path "/" >=> OK "index"
path "/api"
>=> choose [
path "" >=> NO_CONTENT
path "/users" >=> OK """{"api": "users"}"""
]expecting a request to /api would return a 204 No Content response and a request to /api/users would return the JSON-encoded string. To my surprise, I received a 404 Not Found for both. After doing some digging, I discovered that path tests if the given path matches the request path, so with path "/users" above, it compares a request to /api/users with the given /users, fails, and returns None.
I wasn't able to find anything in the existing code base to handle this, so I added the following as a helper module in my application to achieve the expected behavior:
let optionally pred value =
if pred then Some value else None
let getCurrentRoot ctx =
match ctx.userState.TryFind("rootPath") with
| None -> ""
| Some p -> string p
let rootPath (part : string) (ctx : HttpContext) =
let root = getCurrentRoot ctx
{ ctx with userState = ctx.userState.Add("rootPath", root + part) }
|> Some
|> async.Return
let subPath (part : string) (ctx : HttpContext) =
let fullPath = (getCurrentRoot ctx) + part
ctx
|> optionally (fullPath = ctx.request.path)
|> async.Returnallowing the following to work as expected:
let app =
path "/" >=> OK "index"
rootPath "/api"
>=> choose [
// handles requests to `/api`
subPath "" >=> NO_CONTENT
// handles requests to `/api/users`
subPath "/users" >=> OK """{"api": "users"}"""
]I took to Twitter to see if there was an official way of doing this, and the official Twitter handle suggested I open a PR to start a discussion (see: https://twitter.com/SuaveIO/status/823219104995741696). I'm a a big fan of using issues for these types of discussions, but if something like the above is desired for Suave, I'd be happy to submit a PR for any changes.
Does something like this exist today? If not, would it be useful to include this functionality as a part of Suave?