Plug.Router
A DSL to define a routing algorithm that works with Plug.
It provides a set of macros to generate routes. For example:
defmodule AppRouter do
use Plug.Router
import Plug.Conn
plug :match
plug :dispatch
get "/hello" do
send_resp(conn, 200, "world")
end
match _ do
# Halt the request so it doesn't go
# further in the plug stack.
halt send_resp(conn, 404, "oops")
end
end
Each route needs to return a connection, as per the Plug spec.
A catch all match
is recommended to be defined, as in the example
above, otherwise routing fails with a function clause error.
The router is a plug, which means it can be invoked as:
AppRouter.call(conn, [])
Notice the router contains a plug stack and by default it requires
two plugs: match
and dispatch
. match
is responsible for
finding a matching route which is then forwarded to dispatch
.
This means users can easily hook into the router mechanism and add
behaviour before match, before dispatch or after both.
Routes
get "/hello" do
send_resp(conn, 200, "world")
end
In the example above, a request will only match if it is
a GET
request and the route “/hello”. The supported
HTTP methods are get
, post
, put
, patch
, delete
and options
.
A route can also specify parameters which will then be available in the function body:
get "/hello/:name" do
send_resp(conn, 200, "hello #{name}")
end
Routes allow for globbing which will match the remaining parts of a route and can be available as a parameter in the function body, also note that a glob can’t be followed by other segments:
get "/hello/*_rest" do
send_resp(conn, 200, "matches all routes starting with /hello")
end
get "/hello/*glob" do
send_resp(conn, 200, "route after /hello: #{inspect glob}")
end
Finally, a general match
function is also supported:
match "/hello" do
send_resp(conn, 200, "world")
end
A match
will match any route regardless of the HTTP method.
Check match/3
for more information on how route compilation
works and a list of supported options.
Routes compilation
All routes are compiled to a match function that receives three arguments: the method, the request path split on “/“ and the connection. Consider this example:
match "/foo/bar", via: :get do
send_resp(conn, 200, "hello world")
end
It is compiled to:
defp match("GET", ["foo", "bar"], conn) do
send_resp(conn, 200, "hello world")
end
This opens up a few possibilities. First, guards can be given to match:
match "/foo/:bar" when size(bar) <= 3, via: :get do
send_resp(conn, 200, "hello world")
end
Second, a list of splitten paths (which is the compiled result) is also allowed:
match ["foo", bar], via: :get do
send_resp(conn, 200, "hello world")
end
After a match is found, the block given as do/end
is stored
as a function in the connection. This function is then retrieved
and invoked in the dispatch
plug.
Summary
delete(path, contents) | Dispatches to the path only if it is delete request.
See |
forward(path, options) | Forwards requests to another Plug. The path_info of the forwarded
connection will exclude the portion of the path specified in the
call to |
get(path, contents) | Dispatches to the path only if it is get request.
See |
match(expression, options, contents \\ []) | Main API to define routes. It accepts an expression representing the path and many options allowing the match to be configured |
options(path, contents) | Dispatches to the path only if it is options request.
See |
patch(path, contents) | Dispatches to the path only if it is patch request.
See |
post(path, contents) | Dispatches to the path only if it is post request.
See |
put(path, contents) | Dispatches to the path only if it is put request.
See |
Macros
Dispatches to the path only if it is delete request.
See match/3
for more examples.
Forwards requests to another Plug. The path_info of the forwarded
connection will exclude the portion of the path specified in the
call to forward
.
Examples
forward "/users", to: UserRouter
Options
forward
accepts the following options:
:to
- a Plug where the requests will be forwarded
All remaining options are passed to the underlying plug.
Dispatches to the path only if it is get request.
See match/3
for more examples.
Main API to define routes. It accepts an expression representing the path and many options allowing the match to be configured.
Examples
match "/foo/bar", via: :get do
send_resp(conn, 200, "hello world")
end
Options
match
accepts the following options:
:via
- matches the route against some specific HTTP methods:do
- contains the implementation to be invoked in case the route matches
Dispatches to the path only if it is options request.
See match/3
for more examples.
Dispatches to the path only if it is patch request.
See match/3
for more examples.
Dispatches to the path only if it is post request.
See match/3
for more examples.