package routes

  1. Overview
  2. Docs
Typed routing for OCaml applications

Install

Dune Dependency

Authors

Maintainers

Sources

routes-0.7.2.tbz
sha256=ff8f47367ea43879dca1f297944aeea049e31804838b41d5d01cb34b184417a2
sha512=dfa07568ba424c043a5cf9d9dc30b4e78f8f8f4549bcde082b8d5cf33885d93ab443eaefb9127b50b33e3a521dad37e2f38f5c9663fe58c6115013ca32c22f5c

Description

routes provides combinators for adding typed routing to OCaml applications. The core library will be independent of any particular web framework or runtime. It does path based dispatch from a target url to a user provided handler.

Tags

router http

Published: 24 Mar 2020

README

Routes  

This library will help with adding typed routes to OCaml applications. The goal is to have a easy to use portable library with reasonable performance See benchmark folder.

Users can create a list of routes, and handler function to work on the extracted entities using the combinators provided by the library. To perform URL matching one would just need to forward the URL's path to the router.

Example
open Routes

let greet_user name id =
  Printf.sprintf "Hello, %s [%d]" name id
;;

let sum a b =
  Printf.sprintf "%d" (a + b)
;;

(* nil and trail are used to indicate the end of a route.
   nil enforces that the route doesn't end with a trailing slash
   as opposed to trail which enforces a final trailing slash. *)
let router =
  one_of [
    s "sum" / int / int /? nil @--> sum
  ; s "user" / str / int /? trail @--> greet_user
  ]
;;

let () =
  match (match' router ~target:"/sum/1/2") with
  | Some "3" -> ()
  | _ -> assert false
;;

While the library comes with pattern definitions for some common used types like int, int32, string, etc, it allows for custom patterns for user-defined types to be used in the same manner as the pre-defined patterns.

open Routes;;

type shape = Circle | Square

(* a [string -> 'a option] function is needed to define a custom pattern.
   This is what's used by the library to determine whether a path param
   can be successfully coerced into the type or not. *)
let shape_of_string = function
  | "circle" -> Some Circle
  | "square" -> Some Square
  | _ -> None
;;

(* A ['a -> string] function is also needed. This is used when using
   the [sprintf] library function to serialize a route definition into
   a URI target. *)
let shape_to_string = function
  | Circle -> "circle"
  | Square -> "square"
;;

(* When creating a custom pattern, it is recommended to prefix
   the string label with a `:`. This will ensure that when pretty printing
   a route, the output looks consistent with the pretty printers defined
   for the built-in patterns. *)
let shape = pattern shape_to_string shape_of_string ":shape"

let process_shape s = shape_to_string s

let route () = s "shape" / shape / s "create" /? nil

let router = one_of [ route () @--> process_shape ]

let () =
  match' ~target:"/shape/circle/create" router with
  | Some "circle" -> ()
  | _ -> assert false

More example of library usage can be seen in the examples folder, and as part of the test definition.

Installation

To use the version published on opam:
opam install routes
For development version:
opam pin add routes git+https://github.com/anuragsoni/routes.git

Related Work

The combinators are influenced by Rudi Grinberg's wonderful blogpost about type safe routing done via an EDSL using GADTs + an interpreted for the DSL.

Also thanks to Gabriel Radanne for feedback and for the blog post showing the technique used in printf like functions.

Dependencies (2)

  1. dune
  2. ocaml >= "4.05.0"

Dev Dependencies (2)

  1. alcotest with-test
  2. bisect_ppx dev & >= "2.0.0"

Used by (1)

  1. current_web = "0.2"

Conflicts

None

OCaml

Innovation. Community. Security.