Routing Changes in 0.8

A significant part of the 0.8 development cycle has been to improve and upgrade routers. In most cases, the new logic is a drop-in replacement for the old.

If you are upgrading from 0.7 or earlier, and you implement your own routers or routing specifications, you will need to be aware of these changes. This should not affect the vast majority of Pedestal applications.

The naming of routing-related protocols and methods of those protocols is quite confusing; it will take some real work over much time to straighten that out. Focus on what the protocols do rather than how they are named.

In addition, the Sawtooth Router is now the default router; the others are kept primarily for backwards compatibility.

Private Functions

Many of the namespaces used in routing had internal functions not marked as private; these have been made private.

New: Routing Fragment vs. Routing Table

Previously, it was assumed that there was a single specification for all routes; in trivial examples this might be a set (which, via the RouteSpecification protocol) is interpreted as a call to table-routes).

Other applications might invoke table/table-routes directly.

In either case, this single value is provided as the ::http/routes key of the service map.

A single set of routes is now considered a special case; the more general case is that multiple sets of routes will be mixed together to form the overall routing table.

The return type of table-routes/routes, and the other built-in route definitions (terse-routes and expand-verbose-routes) have been changed; previously they returned a seq of route maps; they now return a RoutingFragment (essentially, a wrapper around a seq of route maps).

Likewise, the routes-from macro now accepts a variable number of expressions.

ExpandableRoutes

The ExpandableRoutes protocol is now used to convert an arbitrary data structure to a RoutingFragment (not a seq of expanded routes); these fragments are then combined, by expand-routes, into the full routing table.

Previously, expand-routes only accepted a single value; it now accepts one or more RoutingFragments.

RouterSpecification Protocol

The RouterSpecification protocol was used to choose a different strategy based on whether the routing table was an actual value, or a function that returns a value; the protocol has been removed as there were only ever two implementations.

Router Protocol

The Router protocol, and the containing io.pedestal.http.route.router namespace, have been removed; instead, each router contructor simply returns a router function.

The contract has changed slightly; on a successful route, the router function returns a tuple of two values:

  • The matching route

  • The map of path parameter values (extracted from the request’s path)