1 Matching Annotations
  1. Mar 2024
    1. 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.