Created
August 6, 2014 02:44
-
-
Save gene9/7809d5fd928b00fa521c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We need a better syntax for routing. The dispatch list | |
is both too limited and too inconvenient. | |
This better syntax will be parsed and converted to a more | |
efficient form before it is used, therefore the complexity | |
of the parsing of the routes has no impact on performance. | |
We accept both strings and binaries. | |
First we can match normal paths. | |
"/" | |
"/cars" | |
"/cars/that/your/daddy/owned" | |
We can also bind values. | |
"/cars/:name" | |
"/cars/:name/owner" | |
"/cars/:name/:color" | |
We can have optional path segment or segments. | |
"/cars/[that/your/daddy/owned]" | |
"/cars/[:name]" | |
"/cars/[:name/owner]" | |
"/cars/[:name/:color]" | |
"[/:language]/cars" | |
We can retrieve the rest of the path by using "[...]". | |
This must always be the last segment, and this must also | |
always be inside []s as we don't distinguish empty paths. | |
This is called the path_info. | |
"/cars/[...]" | |
"/cars/[:name/[...]]" | |
As you can see we can have imbricated optional segments. | |
"/cars/[:name/[:color]]" | |
We have the special binding "_" that acts pretty much | |
like in Erlang, it will match any single segment, just | |
discarding its value. | |
"/cars/:_" | |
"/cars/:_/owner" | |
"/cars/:_/:color" | |
"/cars/[:_]" | |
If a binding is defined twice, the values must be identical. | |
"/cars/:name/:name" | |
If a binding is optional, it will only be checked for identity | |
when it is available. | |
"/cars/:name/[:name]" | |
A path rule would look like the following. | |
{"/cars/:name/:color", Handler, Opts} | |
We can put additional constraints on bindings. For example | |
we can check that a value is inside a list of allowed values. | |
Atom values are allowed here and are converted to the expected | |
representation before they are used. | |
{"/cars/:name/:color", [{color, in, [blue, red, pink]}], Handler, Opts} | |
All this also work for hostnames, with the only difference | |
being that "[...]" must be set at the beginning, and that | |
they use dots instead of slashes for segment separators. | |
"ninenines.eu" | |
"[www].ninenines.eu" | |
":name.cardeals.com" | |
"[...].ninenines.eu" | |
A leading dot is ignored, the following two rules are equivalent. | |
"ninenines.eu" | |
".ninenines.eu" | |
If a binding happens twice both in the hostname and the path, they | |
are also checked for identity. | |
":name.cardeals.com" | |
"/cars/:name/:color" | |
A host rule would look like the following. | |
{":name.cardeals.com", ListOfPathRules} | |
A host dispatch rule can also have additional constraints on | |
the bindings. They are valid for the hostname and all the paths | |
defined. This means that if we were to put a constraint in the | |
hostname info about the "name" or the "color" bindings in the | |
previous example, they would also apply to the path. | |
{":name.cardeals.com", [{color, in, [blue, red, pink]}], ListOfPathRules} | |
Constraints can be user defined. | |
{color, fun check_color(C) -> true} | |
The dispatch list end up being as follow. | |
[ListOfHostRules]. | |
It must go through a function before it can be used. | |
cowboy:routing([ListOfHostRules]). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment