docs / NestJS
NestJS Middleware Guide
Master NestJS middleware to intercept and process HTTP requests before they reach your route handlers.
2 min read
Understanding NestJS Middleware
Middleware functions are functions that have access to the request object, the response object, and the next middleware function in the application's request-response cycle. This guide explores how to implement and use middleware effectively in NestJS applications.
What is Middleware?
Middleware functions can perform the following tasks:
- Execute any code
- Make changes to the request and response objects
- End the request-response cycle
- Call the next middleware function in the stack
Creating Middleware
There are two ways to implement middleware in NestJS:
Functional Middleware
import { Request, Response, NextFunction } from 'express';
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request ${req.method} ${req.url}`);
next();
}Class Middleware
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(`Request ${req.method} ${req.url}`);
next();
}
}Applying Middleware
You can apply middleware in several ways:
Module-level Middleware
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('cats');
}
}Global Middleware
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { logger } from './common/middleware/logger.middleware';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
}
bootstrap();Route-specific Middleware
You can apply middleware to specific routes:
consumer.apply(LoggerMiddleware).forRoutes({ path: 'cats', method: RequestMethod.GET });Multiple Middleware
You can apply multiple middleware in sequence:
consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);Excluding Routes
You can exclude specific routes from middleware:
consumer
.apply(LoggerMiddleware)
.exclude(
{ path: 'cats', method: RequestMethod.GET },
{ path: 'cats', method: RequestMethod.POST },
'cats/(.*)'
)
.forRoutes(CatsController);Functional Middleware
For simple middleware, you can use functional middleware:
export function logger(req, res, next) {
console.log(`Request...`);
next();
}Best Practices
- Keep middleware focused on a single responsibility
- Use dependency injection when needed
- Consider performance implications
- Use appropriate error handling
- Test middleware thoroughly
By understanding and implementing middleware correctly, you can create more modular, maintainable, and secure NestJS applications.