Routing
Decide how to respond to a clients request based on the shape of said request.
# Route Argument
Routing is usually done in the middleware
and requestHandler
functions. Both functions take, as their first argument, a Route.t
record. This is a helper composed of useful information from the client's http request.
The Route
module gives functions for pulling data out of the Route.t
record.
1(*
2 Get path ([string list]) of [t].
3 *)
4val path: t -> string list
5
6(*
7 Get http method ([Method.t]) of [t].
8 *)
9val meth: t -> Method.t
10
11(*
12 Get query [sring] of [t].
13 *)
14val rawQuery: t -> string
15
16(*
17 Get query map [string list Query.QueryMap.t] ot [t].
18 *)
19val query: t -> string list Query.QueryMap.t
1/**
2 Get path ([list(string)]) of [t].
3 */
4let path: t => list(string);
5
6/**
7 Get http method ([Method.t]) of [t].
8 */
9let meth: t => Method.t;
10
11/**
12 Get query [sring] of [t].
13 */
14let rawQuery: t => string;
15
16/**
17 Get query map [Query.QueryMap.t(list(string))] ot [t].
18 */
19let query: t => Query.QueryMap.t(list(string));
It is worth noting that
path
is aURI
split by/
characters gathered in alist
. For example:/my/favorite/api/endpoint
would be a list of"my", "favorite", "api", "endpoint"
. This structure allows for easily matching on URI parameters.
# Examples
Routing is most often done via pattern matching. This makes it very simple to route request to functions based on a combination of http method and URI.
1Naboris.ServerConfig.create()
2 |> Naboris.ServerConfig.setRequestHandler((route, req, res) => {
3 switch(Naboris.Route.meth(route), Naboris.Route.path(route)) {
4 | (GET, ["users"]) => // matches /users
5 UserController.getAllUsers(req, res);
6 | (POST, ["users"]) => // matches /users
7 UserController.createUser(req, res);
8 | (GET, ["users", userId]) => // matches /users/:userId with a URI parameter
9 UserController.getUser(userId, req, res);
10 | (PUT, ["users", userId]) => // matches /users/:userId with a URI parameter
11 UserController.updateUser(userId, req, res);
12 | (GET, ["blog", "articles"]) => // matches /blog/articles
13 ArticleController.getAllArticles(req, res);
14 | (_, ["shop", ..._rest]) => // match all request that begin with /shop
15 ShopRouter.routeShopRequest(route, req, res);
16 | _ => // catch any unmatched routes
17 res
18 |> Naboris.Res.status(404)
19 |> Naboris.Res.text(req, 'Not Found');
20 }
21 });
1Naboris.ServerConfig.create()
2 |> Naboris.ServerConfig.setRequestHandler (fun route req res ->
3 match(Naboris.Route.meth route, Naboris.Route.path route) with
4 | (GET, ["users"]) -> (* matches /users *)
5 UserController.get_all_users req res
6 | (POST, ["users"]) -> (* matches /users *)
7 UserController.create_user req res
8 | (GET, ["users"; user_id]) -> (* matches /users/:user_id with a URI parameter *)
9 UserController.get_user userId req res
10 | (PUT, ["users"; user_id]) -> (* matches /users/:user_id with a URI parameter *)
11 UserController.update_user userId req res
12 | (PUT, ["blog"; "articles"]) -> (* matches /blog/articles *)
13 ArticleController.get_all_articles route req res
14 | (_, "shop" :: _rest) -> (* matches all requests that begin with /shop *)
15 ShopRouter.route_shop_request req res
16 | _ -> (* catch any unmatched routes *)
17 res
18 |> Naboris.Res.status 404
19 |> Naboris.Res.text req 'Not Found')