Routing
Routing is responsible for matching incoming HTTP requests and dispatching those requests to the app's HttpHandlers. The breakdown of Endpoint Routing is simple. Associate a specific route pattern and an HTTP verb to an HttpHandler which represents the ongoing processing (and eventual return) of a request.
Bearing this in mind, routing can practically be represented by a list of these "mappings" known in Falco as an HttpEndpoint which bind together: a route, verb and handler.
Note: All of the following examples are fully functioning web apps.
open Falco
open Falco.Routing
open Microsoft.AspNetCore.Builder
let wapp = WebApplication.Create()
let endpoints =
[ get "/" (Response.ofPlainText "hello world") ]
wapp.UseRouting()
.UseFalco(endpoints)
.Run()
The preceding example includes a single HttpEndpoint:
- When an HTTP
GETrequest is sent to the root URL/:- The
HttpHandlershown executes. Hello World!is written to the HTTP response using the Response module.
- The
- If the request method is not
GETor the URL is not/, no route matches and an HTTP 404 is returned.
The following example shows a more sophisticated HttpEndpoint:
open Falco
open Falco.Routing
open Microsoft.AspNetCore.Builder
let wapp = WebApplication.Create()
let endpoints =
[
get "/hello/{name:alpha}" (fun ctx ->
let route = Request.getRoute ctx
let name = route.GetString "name"
let message = sprintf "Hello %s" name
Response.ofPlainText message ctx)
]
wapp.UseRouting()
.UseFalco(endpoints)
.Run()
The string /hello/{name:alpha} is a route template. It is used to configure how the endpoint is matched. In this case, the template matches:
- A URL like
/hello/Ryan - Any URL path that begins with
/hello/followed by a sequence of alphabetic characters.:alphaapplies a route constraint that matches only alphabetic characters.- Full route constraint reference: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing#route-constraint-reference.
The second segment of the URL path, {name:alpha}:
- Is bound to the
nameparameter. - Is captured and stored in
HttpRequest.RouteValues, which Falco exposes through a uniform API to obtain primitive typed values.
An alternative way to express the HttEndpoint above is seen below.
open Falco
open Falco.Routing
open Microsoft.AspNetCore.Builder
let wapp = WebApplication.Create()
let greetingHandler name : HttpHandler =
let message = sprintf "Hello %s" name
Response.ofPlainText message
let endpoints =
[ mapGet "/hello/{name:alpha}" (fun route -> route.GetString "name") greetingHandler ]
wapp.UseRouting()
.UseFalco(endpoints)
.Run()
Multi-method Endpoints
There are scenarios where you may want to accept multiple HTTP verbs to single a URL. For example, a GET/POST form submission.
To create a "multi-method" endpoint, the all function accepts a list of HTTP Verb and HttpHandler pairs.
open Falco
open Falco.Markup
open Microsoft.AspNetCore.Builder
let form =
Templates.html5 "en" [] [
_form [ _method_ "post" ] [
_input [ _name_ "name" ]
_input [ _type_ "submit" ] ] ]
let wapp = WebApplication.Create()
let endpoints =
[
get "/" (Response.ofPlainText "Hello from /")
all "/form" [
GET, Response.ofHtml form
POST, Response.ofEmpty ]
]
wapp.UseRouting()
.UseFalco(endpoints)
.Run()