Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Routes with optional parameters in Suave

Tags:

f#

routing

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:

  • http://localhost:8083/hello/FooBar In this case lang should be set to a default value of "en-GB"
  • http://localhost:8083/hello/FooBar?lang=en-GB
  • http://localhost:8083/hello/FooBar?lang=de-DE

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?

like image 263
dustinmoris Avatar asked Apr 11 '16 11:04

dustinmoris


1 Answers

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" ]
like image 123
Tomas Petricek Avatar answered Oct 23 '22 07:10

Tomas Petricek