lilydocs
HTTP APIWebSocketConsumer
Request processing2 min read

Request-local state

Share data and verified identity between components within the same request.

Request-local state carries data prepared by middleware or a guard to the action. It differs from a DI service scope: it is a request-bound store of typed values, not a service registration.

Publish a value#

Add application data you have already validated to the request. For example, if TenantContext is your application's own type:

Inside middleware or a guard
request.local_mut().insert(tenant_context);

The action receives it through Local<TenantContext> or Option<Local<TenantContext>>. This is an owned clone; use Local<Arc<TenantContext>> for large values.

A missing required Local<T> causes an internal state error. Choose Option when absence is expected; do not bypass a security check by making a required security value optional.

Verified principal#

After authentication completes successfully:

Inside AuthGuard
let principal = self.verifier.verify(request, cancellation).await?;
request.set_principal(principal);

The action's principal: Principal parameter reads this value. Principal::new and set_principal do not verify credentials on their own. Subject, role, scope, and claim data must come from a trusted verifier.

DI scopes and cleanup state#

Service<T> receives a service from the active DI scope. Local<T> receives a value stored in the request. They serve different purposes.

Middleware state retained for abnormal termination is written through exchange.termination_state_mut(). This store is separate from Request.local; see shutdown.

Sources for this page v0.1.0

This guide is based on the reviewed framework commit.

QUICK START
Documentation
Source code