Context Map
Description
The context map is passed to each interceptor’s :enter and :leave functions, and is one of two arguments passed to an interceptor’s :error function.
Pedestal makes use of a number of keys in the context map described below as part of its public API. Further keys may also be present and are officially undefined and are considered an implementation detail subject to change at any time.
Key | Type | Description |
---|---|---|
:bindings |
map of var → value |
See notes below. |
:io.pedestal.interceptor.chain/error |
Exception |
When error processing is invoked, this value is the most recent exception that triggered error handling. |
:io.pedestal.interceptor.chain/execution-id |
Opaque |
This identifier is set uniquely when the interceptor chain is initially executed. It is useful for correlating log events. Do not assume anything about the structure or type of this identifier. |
:io.pedestal.interceptor.chain/queue |
Stack of interceptors |
These are the interceptors left to execute. You can inspect this for debugging purposes, but to manipulate it you should call |
:io.pedestal.interceptor.chain/terminators |
Collection of predicates |
After executing each :enter function, Pedestal checks every predicate in this collection, passing the context map to each one. If any of them returns true-ish, Pedestal begins executing the :leave stack. |
The io.pedestal.interceptor.chain/queue key is removed from the context map once an interceptor chain begins processing the :leave stage. |
:bindings
In ordinary Clojure code, the binding
macro can be used to override the thread-bound values of
dynamic Vars; this is not possible with interceptors, as the interceptor function will return before
the next interceptor is executed.
Instead, an interceptor that needs to override or communicate a value via a dynamic binding will instead modify the :bindings key of the context.
Any bindings associated this way will stay present until they are dissoc
-ed from the :bindings map; a binding
added by one interceptor during the :enter phase will still be present during the :leave phase.
It is not uncommon for an interceptor to provide an :enter function to bind a var, and a corresponding :leave function to remove the binding:
(def ^:dynamic *request-id* nil)
(def request-id-interceptor
{:name ::mdc
:enter (fn [context]
(update context :bindings assoc #'*request-id* (str (random-uuid)))
:leave (fn [context]
(update context :bindings dissoc #'*request-id*))})
As Applied to HTTP
A chain of interceptors can be used for any kind of pipelined processing with branching decisions. It is not limited to HTTP request handling.
When used with Pedestal’s HTTP handling, there are additional keys of interest. The context map is created before the first interceptor is invoked. It describes the context of the interceptor execution itself. When the execution chain is connected to an HTTP server, the :request and :response keys have a special purpose.
Pedestal does not attach metadata to the request map.
When processing, take care to modify the map, rather than constructing a new one. Interceptors may add arbitrary keys to the request map, so it is important to preserve keys that your interceptor does not specifically modify.
Key | Type | Description |
---|---|---|
:request |
Provided by the HTTP chain provider. |
|
:response |
Added by an interceptor or handler, as which point the :enter phase of request processing is completed. |
Servlet Keys
The following context keys are only present when using the Servlet Interceptor:
Key | Type | Description |
---|---|---|
:servlet-request |
HttpServletRequest |
The request that was sent by the client. You should use the request map rather than directly accessing this. |
:servlet-response |
HttpServletResponse |
The response object in which the HTTP server wants its response. You should construct and attach a response map rather than directly accessing this. |
:servlet-config |
javax.servlet.ServletConfig |
The servlet configuration object. |
:servlet |
javax.servlet.Servlet |
The servlet itself. |