package wtr-ppx

  1. Overview
  2. Docs

%routes ppx

wtr-ppx package provides %routes ppx. Which is an alternate and productive approach to defining routes in wtr. They can be used as follows:

  1. [%routes "route-syntax" ] or
  2. {%routes| route-syntax |} - since OCaml 4.11.0

where route-syntax is a string which follows the grammar specified in %routes Syntax.

Demo

let ppx_router =
  Wtr.router'
    [ {%routes| get,post,head,delete  ; /home/about/       |} about_page
    ; {%routes| head,delete           ; /home/:int/        |} prod_page
    ; {%routes| get,post              ; /home/:float/      |} float_page
    ; {%routes| get; /contact/*/:int                       |} contact_page
    ; {%routes| get; /product/:string?section=:int&q=:bool |} product1
    ; {%routes| get; /product/:string?section=:int&q1=yes  |} product2
    ; {%routes| get; /fruit/:Fruit                         |} fruit_page
    ; {%routes|      /                                     |} root_page
    ; {%routes| GET; /faq/:int/**                          |} faq ]

%routes Syntax

In general, the %routes syntax closely mirrors that of a HTTP path1 and query2 syntax. The two notable points of divergence are as follows:

  1. %routes allows to specify HTTP methods applicable to a request target
  2. %routes only allows key=value form of query specification.

Wtr.routes

The %routes ppx - after parsing and validating the syntax and the tokens - transforms to applying the Wtr.routes function. Therefore, the following two are equivalent ways of specifying the same route value:

let routes1 = {%routes| get,post,head,delete  ; /home/about/ |} about_page in 
let routes2 = Wtr.(routes [`GET;`POST;`HEAD;`DELETE] (exact "home" / exact "about" /. slash)) about_page 

We use ABNF notation3 to specify the %routes syntax.

routes-syntax = [http-methods ";" ] http-path ["?" http-query] http-methods = http-method *("," http-method) http-method = "GET" / "HEAD" / "POST" / "PUT" / "DELETE" / "CONNECT" / "OPTIONS" / "TRACE" / other-http-method ; other-http-method is converted to ; [`Method other-http-method] in OCaml other-http-method = 1*ALPHA http-path = "/" wtr-segment wtr-segment = wtr-arg / rest / wildcard / [segment-nz *( "/" segment)] wtr-arg = ":int" / ":int32" / ":int64" / ":float" / ":bool" / ":string" / custom-arg custom-arg = ":" ocaml-module-path ocaml-module-path = module-name *("." module-name) ; OCaml module path ocaml-module-name = (A-Z) *( ALPHA / DIGIT / "_" / "'" ) ; OCaml module name rest = "**" wildcard = "*" segment = *pchar segment-nz = 1*pchar pchar = unreserved / pct-encoded / sub-delims / ":" / "@" unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" pct-encoded = "%" HEXDIG HEXDIG sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" http-query = query-key-value *("&" query-key-value) query-key-value = query-name "=" query-value query-value = 1*pchar / wtr-arg query-name = 1( pchar / "/" / "?" ) qchar = unreserved / pct-encoded / qsub-delims / ":" / "@" qsub-delims = "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / ";" ALPHA = %x41-5A / %x61-7A ; A-Z / a-z DIGIT = %x30-39 ; 0-9 HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"

wtr-segment

  • rest(**) is Wtr.rest
  • wildcard(*) is Wtr.string

wtr-arg

  • :int - is Wtr.int when used in path and Wtr.qint when used in query
  • :int32 - is Wtr.int32 when used in path and Wtr.qint32 when used in query
  • :int64 - is Wtr.int64 when used in path and Wtr.qint64 when used in query
  • :float - is Wtr.float when used in path and Wtr.qfloat when used in query
  • :bool - is Wtr.bool when used in path and Wtr.qbool when used in query
  • :string - is Wtr.string when used in path and Wtr.qstring when used in query
  • :custom-arg - is the OCaml module name which implements the user defined Wtr.arg value, e.g. :Fruit or :LibA.Fruit

References

  1. HTTP path
  2. HtTP query
  3. ABNF
OCaml

Innovation. Community. Security.