package routes

  1. Overview
  2. Docs

Routes

Introduction

Routes is a routing library for OCaml that allows defining type safe routes, to dispatch a request to a matching handler, based on path parameters in the input URI target. Type safe in this context, refers to processing the input URI in a manner that assigns concrete types to the values extracted from the path parameters.

The library has no external dependencies aside from the OCaml standard library, and it can be used in both native (via ocamlopt) and javascript usecases (via js_of_ocaml). It isn't tied to any particular framework, with the intention for frameworks to provide a higher level wrapper around it.

Installation

Routes is published on the opam repository. If using opam, install it via

stable version:

opam install routes 

development version:

opam pin add routes.dev git+https://github.com/anuragsoni/routes.git 

If using esy, add the dependency @opam/routes to package.json/esy.json. Or you can use esy add @opam/routes to add it to the manifest file automatically.

Usage

open Routes
open Infix

(* val greet_user : string -> int -> string *)
let greet_user name id =
  Printf.sprintf "Hello, %s [%d]" name id

let add_user name id is_admin =
  Printf.sprintf "Added user %s with id %d. IsAdmin? %b" name id is_admin

let routes =
  with_method
    [ `GET, greet_user <$> s "user" *> str </> s "id" *> int
    ; `POST, add_user <$> s "user" *> str </> int </> bool
    ]

match match_with_method routes ~target:"/user/john/id/12" ~meth:`GET with
| Some response -> response
| None -> "No match"

Using routes as an Opium middleware

open Opium.Std

let to_meth = function
  | `GET -> `GET
  | `POST -> `POST
  | `HEAD -> `HEAD
  | `DELETE -> `DELETE
  | `PATCH -> `Other "PATCH"
  | `PUT -> `PUT
  | `OPTIONS -> `OPTIONS
  | `TRACE -> `TRACE
  | `CONNECT -> `CONNECT
  | `Other w -> `Other w

let router routes =
  let open Routes in
  let filter handler req =
    let target = Request.uri req |> Uri.path in
    let meth = Request.meth req in
    match match_with_method routes ~target ~meth:(to_meth meth) with
    | None -> handler req
    | Some h -> h req
  in
  Rock.Middleware.create ~name:"Routes" ~filter

(* This can be used with any opium app now *)

open Routes
open Infix

type person =
  { name : string
  ; age : int
  }

let json_of_person { name; age } =
  let open Ezjsonm in
  dict [ "name", string name; "age", int age ]
;;

let hello (_ : Request.t) = `String "Hello World!" |> respond'

let routes =
  with_method [ `GET, hello <$ empty; `GET, print_person <$> s "person" *> str </> int ]

let () =
  App.empty
  |> middleware (router routes)
  |> App.run_command

Routes ships with patterns that match the following types: int, int32, int64, bool, string, but it is possible to define custom patterns that can be used to extract path parameters that can be parsed into a user defined type.

type shape =
  | Square
  | Circle

let shape_of_string = function
  | "square" -> Some Square
  | "circle" -> Some Circle
  | _ -> None

let shape_to_string = function
  | Square -> "square"
  | Circle -> "circle"

(* "<shape>" will be used when printing the route
   as a human readable pattern. *)
let shape = Routes.pattern shape_of_string "<shape>"

(* Now the shape pattern can be used just like any
   of the built in patterns like int, bool etc *)
let router = Routes.(one_of [ shape_to_string <$> s "shape" *> shape ])

Support

Routes' git repository is located on Github. Use the repository's issue tracker to file bug reports and feature requests.

License

Routes is distributed under the BSD-3-clause license.

API documentation

  • Routes Typed routing for OCaml. Routes provides combinators for adding typed routing to OCaml applications. The core library will be independent of any particular web framework or runtime.
OCaml

Innovation. Community. Security.