Hello OCaml community!
It’s my pleasure to announce a new ppx for deriving Dream routers based on variant type declarations, ppx_deriving_router.
A small example. First we define routes (the signature showcases the generated code):
module Pages : sig
...
val href : t -> string
(** generate URL from the route *)
val http_method : t -> [ `DELETE | `GET | `POST | `PUT ]
(** HTTP method for the route *)
val handle : (t -> Dream.handler) -> Dream.handler
(** create a route handler *)
end = struct
open Ppx_deriving_router_runtime.Primitives
type t =
| Home [@GET "/"]
| About
| Hello of { name : string; repeat : int option } [@GET "/hello/:name"]
[@@deriving router]
end
Then we describe how we handle each route:
let handle =
Pages.handle (fun route _req ->
match route with
| Home -> Dream.respond "Home page!"
| About -> Dream.respond "About page!"
| Hello { name; repeat } ->
let name =
match repeat with
| Some repeat ->
List.init repeat (fun _ -> name) |> String.concat ", "
| None -> name
in
Dream.respond (Printf.sprintf "Hello, %s" name))
let () = Dream.run ~interface:"127.0.0.1" ~port:8080 handle
Using generated Pages.href
function we can generate URLs for routes:
let () =
assert (Pages.href Home = "/");
assert (Pages.href About = "/about");
assert (Pages.href (Hello { name = "world"; repeat = None }) = "/hello/world");
assert (Pages.href (Hello { name = "world"; repeat = Some 3 }) = "/hello/world?repeat=3")
The URL matching is done by routes library.
There’s also support for routes that track their response types and the ppx automatically derives JSON encoders and decoders for them (by using melange-json.ppx).
On top of that a separate ppx is provided for Melange which allows to construct type safe HTTP clients (route defintions are shared between server and client).
Happy hacking!