Important Protocols

The major parts of Pedestal are isolated via Clojure protocols. The protocols are for internal structure and external extension. This reference identifies the most important protocols in Pedestal’s structure and how you might use them in an application.

Interceptor Protocols


IntoInterceptor allows pretty much anything to become an interceptor when needed.

Routers use this when building routes: anything that satisfies IntoInterceptor is legal to use in the interceptor vector of a route.

This protocol also comes into play when appending new interceptors to the queue.

Pedestal extends IntoInterceptor onto a variety of Clojure and Java types. See the interceptors reference for details of their behaviors.

Routing Protocols

These protocols break up the lifecycle of routes and allow both extension points and alternative strategies in several places.

Over time, Pedestal has evolved several data structures for representing routing of HTTP requests; each of these data structures is a kind of routing specification. The routing specification ultimately expresses which details of an incoming request, such as HTTP method or URI path, are used to find a specific route (and the interceptors and handler for that route).

In parallel to the data structures, Pedestal has several algorithms for using the routing specification to dispatch an incoming request; some algorithms may be most efficient for small services with very few routes, others are better for large services with more (and more complex) routes.

The protocols described here are what allow the individual pieces to cooperate; this also means that it is possible to define an application-specific routing specification format and use it with a Pedestal-supplied algorithm, or use any of the built-in routing specifications combined with an application-specific algorithm.


The combination of routing specification with a routing algorithm results in an instance of the Router interface.

The Router protocol defines just one function: find-route. find-route is passed the Router itself and a request map, and must return the route map for the route that it matched. The route map not only identifies the interceptors and handler to add to the interceptor queue, but further captures path variables that may be part of the matched URL (further details TBD).

An instance of Router is returned by the router constructor identified in the application’s service map by the key :io.pedestal.http/router.

::http/router Value



Linear Search Router


Prefix Tree Router


Map Tree Router

application-supplied function

The function itself, called with sequence of routes as returned by from the RouterSpecification instance

Whether built-in, or supplied by the application, the constructor is just a function that is passed an expanded route specification, and returns an instance of Router.


The RouterSpecification protocol is used to create a routing interceptor from some definition of routes, and a single Router. This is the final step in the process of turning a routing specification into a routing interceptor.

Whatever is returned from the router-spec function of the protocol must be an interceptor. The returned interceptor will include an :enter function that must accept a context map and enqueue interceptors based on whatever criteria it chooses.


ExpandableRoutes can convert all kinds of data structures representing a routing specification into a single canonical format that can be used to construct a Router. This occurs inside the expand-routes function.

Pedestal provides implementations of ExpandableRoutes for several types:




Terse Syntax


Verbose Syntax


Table Syntax

Since the call to expand-routes comes from application code, it would be rare for an application to need to extend ExpandableRoutes.

The result of expand-routes is a seq of maps that will be passed to the Router.

Servlet Protocols


This protocol applies to anything that can be in the :body key of a response map. The two functions in the protocol tell Pedestal what content type the body implies, and how to serialize the body to an output stream.

Pedestal extends this protocol to several Java and Clojure types to produce the behavior detailed in Response Bodies.

Applications should not assume any output stream type more specific than


This protocol is a more specific version of WritableBody. If the value in the :body key of a response map satisfies WritableBodyAsync, then Pedestal treats it as a streaming result. See Streaming Responses for full details.

It would be rare for an application to extend this protocol. Most of the time, an application would be better off providing an NIO channel or a core.async channel in the response body.