<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>index (wtr-ppx.index)</title><link rel="stylesheet" href="../odoc.css"/><meta charset="utf-8"/><meta name="generator" content="odoc 91f631096"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="#">Up</a> – <a href="#">wtr-ppx</a> &#x00BB; index</nav><header class="odoc-preamble"><h1 id="%routes-ppx"><a href="#%routes-ppx" class="anchor"></a>%routes ppx</h1><p><code>wtr-ppx</code> package provides <code>%routes</code> ppx. Which is an alternate and productive approach to defining <i>route</i>s in <code>wtr</code>. They can be used as follows:</p><ol><li><code>[%routes &quot;route-syntax&quot; ]</code> or</li><li><code>{%routes| route-syntax |}</code> - <i>since OCaml 4.11.0</i></li></ol><p>where <code>route-syntax</code> is a string which follows the grammar specified in <a href="#syntax">%routes Syntax</a>.</p></header><nav class="odoc-toc"><ul><li><a href="#demo">Demo</a></li><li><a href="#syntax">%routes Syntax</a><ul><li><a href="#wtr.routes">Wtr.routes</a></li><li><a href="#wtr-segment">wtr-segment</a></li><li><a href="#wtr-arg">wtr-arg</a></li></ul></li><li><a href="#references">References</a></li></ul></nav><div class="odoc-content"><h3 id="demo"><a href="#demo" class="anchor"></a>Demo</h3><pre><code>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&amp;q=:bool |} product1
    ; {%routes| get; /product/:string?section=:int&amp;q1=yes  |} product2
    ; {%routes| get; /fruit/:Fruit                         |} fruit_page
    ; {%routes|      /                                     |} root_page
    ; {%routes| GET; /faq/:int/**                          |} faq ]</code></pre><h2 id="syntax"><a href="#syntax" class="anchor"></a>%routes Syntax</h2><p>In general, the <code>%routes</code> syntax closely mirrors that of a HTTP <i>path</i><sup>1</sup> and <i>query</i><sup>2</sup> syntax. The two notable points of divergence are as follows:</p><ol><li><code>%routes</code> allows to specify HTTP methods applicable to a <i>request target</i></li><li><code>%routes</code> only allows <code>key=value</code> form of query specification.</li></ol><h3 id="wtr.routes"><a href="#wtr.routes" class="anchor"></a>Wtr.routes</h3><p>The <code>%routes</code> ppx - after parsing and validating the syntax and the tokens - transforms to applying the <a href="../wtr/Wtr/index.html#val-routes"><code>Wtr.routes</code></a> function. Therefore, the following two are equivalent ways of specifying the same <i>route</i> value:</p><pre><code>let routes1 = {%routes| get,post,head,delete  ; /home/about/ |} about_page in 
let routes2 = Wtr.(routes [`GET;`POST;`HEAD;`DELETE] (exact &quot;home&quot; / exact &quot;about&quot; /. slash)) about_page </code></pre><p>We use <i>ABNF notation</i><sup>3</sup> to specify the <code>%routes</code> syntax.</p>
<pre><div class="code hljs abnf">
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"
</code></pre>
<h3 id="wtr-segment"><a href="#wtr-segment" class="anchor"></a>wtr-segment</h3><ul><li>rest<code>(**)</code> is <a href="../wtr/Wtr/index.html#val-rest"><code>Wtr.rest</code></a></li><li>wildcard<code>(*)</code> is <a href="../wtr/Wtr/index.html#val-string"><code>Wtr.string</code></a></li></ul><h3 id="wtr-arg"><a href="#wtr-arg" class="anchor"></a>wtr-arg</h3><ul><li><code>:int</code> - is <a href="../wtr/Wtr/index.html#val-int"><code>Wtr.int</code></a> when used in path and <a href="../wtr/Wtr/index.html#val-qint"><code>Wtr.qint</code></a> when used in query</li><li><code>:int32</code> - is <a href="../wtr/Wtr/index.html#val-int32"><code>Wtr.int32</code></a> when used in path and <a href="../wtr/Wtr/index.html#val-qint32"><code>Wtr.qint32</code></a> when used in query</li><li><code>:int64</code> - is <a href="../wtr/Wtr/index.html#val-int64"><code>Wtr.int64</code></a> when used in path and <a href="../wtr/Wtr/index.html#val-qint64"><code>Wtr.qint64</code></a> when used in query</li><li><code>:float</code> - is <a href="../wtr/Wtr/index.html#val-float"><code>Wtr.float</code></a> when used in path and <a href="../wtr/Wtr/index.html#val-qfloat"><code>Wtr.qfloat</code></a> when used in query</li><li><code>:bool</code> - is <a href="../wtr/Wtr/index.html#val-bool"><code>Wtr.bool</code></a> when used in path and <a href="../wtr/Wtr/index.html#val-qbool"><code>Wtr.qbool</code></a> when used in query</li><li><code>:string</code> - is <a href="../wtr/Wtr/index.html#val-string"><code>Wtr.string</code></a> when used in path and <a href="../wtr/Wtr/index.html#val-qstring"><code>Wtr.qstring</code></a> when used in query</li><li><code>:custom-arg</code> - is the OCaml module name which implements the user defined <a href="../wtr/Wtr/index.html#type-arg"><code>Wtr.arg</code></a> value, e.g. <code>:Fruit</code> or <code>:LibA.Fruit</code></li></ul><h2 id="references"><a href="#references" class="anchor"></a>References</h2><ol><li><a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">HTTP path</a></li><li><a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">HtTP query</a></li><li><a href="https://datatracker.ietf.org/doc/html/rfc5234#section-3.6">ABNF</a></li></ol></div></body></html>