Search code examples
f#routessuave

Routes with optional parameters in Suave


I have a web service with a hello world endpoint like this:

let app =
  choose [ 
      GET >=> 
        choose [ 
          path "/hello" >=> OK "Hello World!"
          pathScan "/hello/%s" (fun name -> OK (sprintf "Hello World from %s" name)) ]
      NOT_FOUND "Not found" ]

[<EntryPoint>]
let main argv = 
  startWebServer defaultConfig app
  0

Now I would like to add an additional endpoint which can handle routes like this: http://localhost:8083/hello/{name}?lang={lang}

This route should work for the following URLs:

but it should not work for

http://localhost:8083/hello/FooBar/en-GB

Optional parameters should only be allowed in a query parameter string and not in the path.

Any idea how to achieve this with Suave?


Solution

  • For handling query parameters, I would probably just use the request function, which gives you all the information about the original HTTP request. You can use that to check the query parameters:

    let handleHello name = request (fun r ->
      let lang = 
        match r.queryParam "lang" with
        | Choice1Of2 lang -> lang
        | _ -> "en-GB"
      OK (sprintf "Hello from %s in language %s" name lang)) 
    
    let app =
      choose [ 
          GET >=> 
            choose [ 
              path "/hello" >=> OK "Hello World!"
              pathScan "/hello/%s" handleHello ]
          NOT_FOUND "Not found" ]