Pipeline order
For a single matched route, nestrs composes Axum middleware in this sequence (outermost to innermost on the incoming path):HttpException values, and the global stack applies final transformations (CORS headers, compression, production error sanitization).
NestJS teaches guards → interceptors → pipes → handler. nestrs respects a similar model but the exact nesting differs — exception filters are outermost. Refer to this page as the authoritative contract for nestrs, not a line-for-line NestJS clone.
Guards — CanActivate
Guards run before the handler and decide whether the request is allowed to proceed. Implement the CanActivate trait:
GuardError produces a JSON error response:
GuardError::unauthorized(message)→ 401 UnauthorizedGuardError::forbidden(message)→ 403 Forbidden
Applying guards
- Route level (impl_routes!)
- Controller level
- Route macro (#[use_guards])
Declare guards per route inside
impl_routes! with the with (G1, G2) syntax. Guards are evaluated left-to-right; the first failure short-circuits.Pipes — PipeTransform
Pipes transform or validate a single value before it reaches the handler. nestrs includes two built-in pipes:
ParseIntPipe— parses a decimal string intoi64ValidationPipe— runsvalidator::Validateon a struct
PipeTransform for custom pipes:
Applying pipes with #[use_pipes]
#[use_pipes(ValidationPipe)] switches #[param::body], #[param::query], and #[param::param] wiring to ValidatedBody, ValidatedQuery, and ValidatedPath extractors, which run validation at extraction time:
PipeTransform::transform directly in handler code without the macro:
Interceptors — Interceptor
Interceptors provide around-advice: they run logic before calling next.run(req) (pre-handler) and can inspect or modify the response after (post-handler). The built-in LoggingInterceptor shows the pattern:
Applying interceptors
- Route level
- Global level
#[use_interceptors(I1, I2, …)] is the outermost Tower layer — it sees the request first and wraps next. On the response path, I1 runs last (outermost on the way back out).
Exception filters — ExceptionFilter
Exception filters intercept HttpException responses before they reach the client. Implement ExceptionFilter to rewrite error responses — for example, to translate error codes, add correlation IDs, or format errors for a specific API contract:
Applying exception filters
- Route level
- Global level
#[use_filters(F1, F2, …)] is the outermost Tower layer. When an HttpException response bubbles up, the innermost filter (closest to the handler) catches it first, then the next filter outward.
Global middleware stack
Beyond per-route cross-cutting concerns, nestrs assembles a global middleware stack inNestApplication::build_router. The layers (from inner to outer on the incoming request) include:
- Optional global exception filter
- CORS
- Security headers
- Rate limiting
- Timeouts
- Request ID injection
- Compression and request decompression
- CSRF (when enabled)
- Cookie and session layers
- Your custom
use_global_layercallbacks (outermost)