mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-16 05:00:24 +00:00
Finish the routing chapter of the guide
Note that this is the new routing not yet available in master. The code should follow in a few days.
This commit is contained in:
parent
efdf3a3433
commit
6f552005f2
1 changed files with 84 additions and 5 deletions
|
@ -90,10 +90,12 @@ PathMatch3 = "/path/to/resource/".
|
|||
```
|
||||
|
||||
Hosts with and without a trailing dot are equivalent for routing.
|
||||
Similarly, hosts with and without a leading dot are also equivalent.
|
||||
|
||||
``` erlang
|
||||
HostMatch1 = "cowboy.example.org".
|
||||
HostMatch2 = "cowboy.example.org.".
|
||||
HostMatch3 = ".cowboy.example.org".
|
||||
```
|
||||
|
||||
It is possible to extract segments of the host and path and to store
|
||||
|
@ -115,16 +117,93 @@ segment value where they were defined. For example, the URL
|
|||
`http://test.example.org/hats/wild_cowboy_legendary/prices` will
|
||||
result in having the value `test` bound to the name `subdomain`
|
||||
and the value `wild_cowboy_legendary` bound to the name `hat_name`.
|
||||
They can later be retrieved using `cowboy_req:binding/{2,3}`.
|
||||
They can later be retrieved using `cowboy_req:binding/{2,3}`. The
|
||||
binding name must be given as an atom.
|
||||
|
||||
@todo special binding `'_'`
|
||||
@todo optional path or segments
|
||||
@todo same binding twice (+ optional + host/path)
|
||||
There is a special binding name you can use to mimic the underscore
|
||||
variable in Erlang. Any match against the `_` binding will succeed
|
||||
but the data will be discarded. This is especially useful for
|
||||
matching against many domain names in one go.
|
||||
|
||||
``` erlang
|
||||
HostMatch = "ninenines.:_".
|
||||
```
|
||||
|
||||
Similarly, it is possible to have optional segments. Anything
|
||||
between brackets is optional.
|
||||
|
||||
``` erlang
|
||||
PathMatch = "/hats/[page/:number]".
|
||||
HostMatch = "[www.]ninenines.eu".
|
||||
```
|
||||
|
||||
You can also have imbricated optional segments.
|
||||
|
||||
``` erlang
|
||||
PathMatch = "/hats/[page/[:number]]".
|
||||
```
|
||||
|
||||
You can retrieve the rest of the host or path using `[...]`.
|
||||
In the case of hosts it will match anything before, in the case
|
||||
of paths anything after the previously matched segments. It is
|
||||
a special case of optional segments, in that it can have
|
||||
zero, one or many segments. You can then find the segments using
|
||||
`cowboy_req:host_info/1` and `cowboy_req:path_info/1` respectively.
|
||||
They will be represented as a list of segments.
|
||||
|
||||
``` erlang
|
||||
PathMatch = "/hats/[...]".
|
||||
HostMatch = "[...]ninenines.eu".
|
||||
```
|
||||
|
||||
Finally, if a binding appears twice in the routing rules, then the
|
||||
match will succeed only if they share the same value. This copies
|
||||
the Erlang pattern matching behavior.
|
||||
|
||||
``` erlang
|
||||
PathMatch = "/hats/:name/:name".
|
||||
```
|
||||
|
||||
This is also true when an optional segment is present. In this
|
||||
case the two values must be identical only if the segment is
|
||||
available.
|
||||
|
||||
``` erlang
|
||||
PathMatch = "/hats/:name/[:name]".
|
||||
```
|
||||
|
||||
If a binding is defined in both the host and path, then they must
|
||||
also share the same value.
|
||||
|
||||
``` erlang
|
||||
PathMatch = "/:user/[...]".
|
||||
HostMatch = ":user.github.com".
|
||||
```
|
||||
|
||||
Constraints
|
||||
-----------
|
||||
|
||||
@todo Describe constraints.
|
||||
After the matching has completed, the resulting bindings can be tested
|
||||
against a set of constraints. The match will succeed only if they all
|
||||
succeed.
|
||||
|
||||
They are always given as a two or three elements tuple, where the first
|
||||
element is the name of the binding, the second element is the constraint's
|
||||
name, and the optional third element is the constraint's arguments.
|
||||
|
||||
The following constraints are currently defined:
|
||||
|
||||
* {Name, int}
|
||||
* {Name, function, (fun(Value) -> true | {true, NewValue} | false)}
|
||||
|
||||
The `int` constraint will check if the binding is a binary string
|
||||
representing an integer, and if it is, will convert the value to integer.
|
||||
|
||||
The `function` constraint will pass the binding value to a user specified
|
||||
function that receives the binary value as its only argument and must
|
||||
return whether it fulfills the constraint, optionally modifying the value.
|
||||
|
||||
Note that constraint functions SHOULD be pure and MUST NOT crash.
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue