Middleware
Middleware
Middleware is a function that runs before the route handler, with access to the request and response objects. If you know Express middleware, this is the same concept — NestJS simply gives it structure and ties it into the module system. It is the first thing to run in the request lifecycle.
What middleware is for
Middleware handles cross-cutting concerns that happen before routing logic: request logging, attaching properties to the request, raw-body parsing, CORS, and similar low-level tasks. It can run code, modify req/res, end the request, or call next() to continue.
Functional middleware
The simplest form is a plain function:
next() nor sends a response, the request hangs forever. This is the most common middleware bug.
Class middleware
For middleware that needs dependencies injected, implement the NestMiddleware interface:
Applying middleware
Middleware is not declared in @Module() metadata. Instead, the module implements NestModule and configures it in a configure() method:
You can target specific routes, methods, or controllers, and use .exclude() to skip some paths.
Middleware vs guards vs interceptors
Middleware runs first, before NestJS even knows which route or handler will run. That makes it perfect for generic, route-agnostic work — but it is the wrong tool for authorization or response shaping:
- Middleware — generic pre-processing (logging, headers, raw body). No access to which handler runs.
- Guards — authorization decisions, with full execution context.
- Interceptors — wrap the handler to transform the request/response.
Summary
Middleware runs first in the request lifecycle, before guards, pipes, and the handler. Write it as a function or a NestMiddleware class, and apply it via a module's configure(consumer) method targeting specific routes. Use it for generic pre-processing — and reach for guards or interceptors when you need NestJS context. Next: guards, which decide whether a request is allowed to proceed.