Unlocking the Power of NestJS Interceptors
NestJS interceptors are a powerful tool in the request-response pipeline, allowing developers to modify or extend the behavior of their applications. In this article, we’ll delve into the world of NestJS interceptors, exploring what they are, how to use them, and some common use cases.
What are NestJS Interceptors?
Interceptors are classes that implement the NestInterceptor
interface, which provides two methods: intercept
and handleRequest
. The intercept
method is called before sending the request to a controller, while the handleRequest
method is called after the request has been processed by the controller and a response is returned.
Creating a Custom Interceptor
To create a custom interceptor, you’ll need to create a class that implements the NestInterceptor
interface. For example, let’s create an interceptor that logs the request method and URL:
“`typescript
import { Injectable } from ‘@nestjs/common’;
import { NestInterceptor, ExecutionContext, CallHandler } from ‘@nestjs/common’;
@Injectable()
export class LoggerInterceptor implements NestInterceptor {
async intercept(context: ExecutionContext, handler: CallHandler) {
const request = context.switchToHttp().getRequest();
console.log(Request method: ${request.method}
);
console.log(Request URL: ${request.url}
);
return handler.handle();
}
}
“`
Binding Interceptors in NestJS
To use an interceptor in your NestJS application, you’ll need to bind it to a controller or a route. There are three ways to bind an interceptor:
- Global-scoped: Use the
useGlobalInterceptors
method in the main.ts file to apply the interceptor to all controllers and routes. - Controller-scoped: Use the
@UseInterceptors
decorator above a controller to apply the interceptor to all routes within that controller. - Route-scoped: Use the
@UseInterceptors
decorator above a specific route to apply the interceptor only to that route.
Use Cases for NestJS Interceptors
Interceptors can be used in a variety of scenarios, including:
- Logging: Log requests and responses to monitor application performance and debug issues.
- Data validation: Validate request data before it reaches the controller.
- Authentication and authorization: Protect routes and ensure only authorized users can access them.
- Exception mapping: Override default exceptions with custom error messages.
Example Use Case: Data Validation
Let’s say we have a POST route that creates a new user. We can use an interceptor to validate the request data before it reaches the controller:
“`typescript
import { Injectable } from ‘@nestjs/common’;
import { NestInterceptor, ExecutionContext, CallHandler } from ‘@nestjs/common’;
@Injectable()
export class DataValidationInterceptor implements NestInterceptor {
async intercept(context: ExecutionContext, handler: CallHandler) {
const request = context.switchToHttp().getRequest();
const userData = request.body;
if (!userData.firstName || !userData.lastName) {
throw new Error(‘First name and last name are required’);
}
return handler.handle();
}
}
“`
By using interceptors, you can decouple logic from your controllers and make your application more scalable and maintainable. Whether it’s logging, data validation, or authentication, interceptors provide a powerful tool for modifying and extending the behavior of your NestJS application.