Просмотр исходного кода

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.
Loïc Hoguin 12 лет назад
Родитель
Сommit
6f552005f2
1 измененных файлов с 84 добавлено и 5 удалено
  1. 84 5
      guide/routing.md

+ 84 - 5
guide/routing.md

@@ -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
 -----------