Skip to content
altitude edited this page Nov 14, 2014 · 4 revisions

Dispatching

This page describes the configuration of URI dispatching to resources in a Webmachine application. The dispatch map data structure is a list of tuples. The tuple can either be a 3-tuples of the form {pathspec, resource, args}, or a 4-tuple of the form {pathspec, guard, resource, args}.

The first entry in the list with a pathspec that matches the URI for a request, will cause the corresponding resource to be used in handling that request. If a guard is provided, then the guard is also checked, and must return true in order for the resource to handle the request.

A pathspec is a list of pathterms. A pathterm is any of [string,atom,star] where star is just the atom of ‘*’. The pathspec-matching is done by breaking up the request URI into tokens via the / separator and matching those tokens against the pathterms. A string pathterm will match a token if the token is equal to that string. A non-star atom will match any single token. The star atom (* in single quotes) will match any number of tokens, but may only be present as the last pathterm in a pathspec. If all tokens are matched and all pathterms are used, then the pathspec matches. The tokens used are available in wrq:path_tokens(ReqData) in the resource functions.

Any atom pathterms that were used in a match will cause a binding in the path_info element of the request’s [[ReqData|Request Data API]]. If there was a foo atom that matched the token “bar”, then wrq:path_info(foo, ReqData) will return “bar” inside the resource calls, and in any case wrq:path_info(ReqData) will return a Dict term with all the bindings, accessible via the dict standard library module. If there was a star pathterm in the pathspec, then wrq:disp_path(ReqData) in a resource function will return the URI portion that was matched by the star.

The guard is an Erlang function of arity 1 (ie: fun my_guard/1) or a 2-tuple of the form {module, function} that refers to a function of arity 1. The guard function should accept a [[ReqData|Request Data API]] object and return a boolean: ‘true’ if the resource can be used for the request, ‘false’ otherwise.

The resource is an atom identifying a resource module that should handle a matching request. It will have the args (which must be a list) passed to its init function before request handling begins.

In the default directory structure for a new Webmachine application, the dispatch terms will be in the dispatch/0 function in src/yourapplication_config.erl under the application root.

Examples

The examples below are taken from Justin Sheehy's slide at Erlang Factory 2009

DISPATCH RULE URL WRQ:DISP_PATH WRQ:PATH WRQ:PATH_INFO WRQ:PATH_TOKENS
{[“a”], some_resource, []} /a ”” “/a” [] []
{[“a”, ‘*’], some_resource, []} /a ”” “/a” [] []
{[“a”, ‘*’], some_resource, []} /a/b/c “b/c” “/a/b/c” [] [“b”, “c”]
{[“a”, foo], some_resource, []} /a/b ”” “/a/b” [{foo, “b”}] []
{[“a”, foo, ‘*’], some_resource, []} /a/b ”” “/a/b” [{foo, “b”}] []
{[“a”, foo, ‘*’], some_resource, []} /a/b/c/d “c/d” “/a/b/c/d” [{foo, “b”}] [“c”, “d”]
{[“a”], fun my_guard/1, some_resource, []} /a ”” “/a” [] []
{[“a”], {my_module, my_guard}, some_resource, []} /a ”” “/a” [] []

Query strings are easy too:

  • Given rule: {[“a”, foo, ‘*’], some_resource, []}
  • And URL: /a/b/c/d?fee=ah&fie=ha
  • Then wrq:get_qs_value(“fie”,ReqData) -> “ha”
Clone this wiki locally