Please be aware that such a routex can create a conflict and unexpected behaviour if you have a similar matching routef (see routef): let webApp = choose [ routex "/foo(/*)" >=> text "Bar" routef "/foo/%s/%s/%s" (fun (s1, s2, s3) -> text (sprintf "%s%s%s" s1 s2 s3)) // If none of the routes matched then return a 404 RequestErrors.NOT_FOUND "Not Found" ] In the above scenario it is not clear which one of the two http handlers a user want to be invoked when a request is made to https://example.org/foo///.
BUG: This will never match foo///
:
routef "/foo/%s/%s/%s" (fun (s1, s2, s3) -> text (sprintf "%s%s%s" s1 s2 s3))
In fact, if the routex
pipeline is removed, the routef
one will be skipped as it does not match foo///
. Perhaps it did in past versions?
SUGGESTION: If the routef
pipeline is replaced with a real conflicting pipeline, such as
route "/foo >=> text "Foo"
then there the order of the pipelines will decide. Even the Giraffe docs say this about choose
:
The
choose
combinator function iterates through a list of HttpHandler functions and invokes each individual handler until the first HttpHandler returns a positive result:
The phrasing is a bit misleading, because it is absolutely clear which of the two handlers will be invoked.