Middleware runs before a request reaches a route handler, exactly as in Express. This lesson covers writing NestJS middleware as functions or classes, and applying it to specific routes.
What Is NestJS Middleware?
NestJS middleware is essentially Express (or Fastify) middleware, a function with access to the request, response, and a next() function, executed before guards, interceptors, pipes, and the route handler itself.
Nest supports two styles: simple functional middleware, and class-based middleware implementing the NestMiddleware interface, which can use dependency injection.
Class-based middleware implements a single use() method with the exact same signature as an Express middleware function, but can inject other providers through its constructor.
Functional middleware is a plain function and cannot use dependency injection, it's best for simple, stateless logic like request logging. Class-based middleware can inject other providers (like a ConfigService), making it the better choice whenever middleware needs access to application services.
Where Middleware Fits in the Request Pipeline
Middleware runs earliest in the pipeline, before guards, interceptors, and pipes. This makes it well suited for cross-cutting concerns that apply broadly (logging, request ID tagging, raw body capture), while guards and pipes are better suited for concerns tied specifically to a given route's authorization or input shape.
Common Mistakes
Forgetting to call next(), which stalls the request indefinitely.
Reaching for middleware when a guard or interceptor would fit the concern better (e.g. authorization logic belongs in a guard, not middleware).
Registering middleware in @Module() metadata instead of the configure() method.
Using functional middleware when the logic actually needs an injected provider.
Key Takeaways
NestJS middleware follows the exact same signature as Express middleware.
Class-based middleware implements NestMiddleware and supports dependency injection.
Middleware is registered via a module's configure() method with MiddlewareConsumer.
Middleware runs before guards, interceptors, and pipes in the request pipeline.
Pro Tip
Reserve middleware for concerns that genuinely don't belong to a specific route's business logic, request logging, correlation IDs, raw body capture for webhooks. Authorization and input validation almost always belong in a guard or pipe instead, where they're easier to test in isolation.
You now understand NestJS middleware. Next, learn about Guards, which control whether a request is allowed to proceed at all.