How to Create a Module in NestJS That Bypasses Global Interceptors, Filters, and Guards
- 588Words
- 3Minutes
- 19 Jul, 2024
In developing a NestJS application, there are times when we need certain modules (such as SpecialModule) to bypass global interceptors (useGlobalInterceptors), filters (useGlobalFilters), and guards (useGlobalGuards). This article will show you how to create a special SpecialModule in NestJS by manually adding logic to global interceptors, filters, and guards to skip the routes of SpecialModule.
Step 1: Create SpecialModule
First, create a SpecialModule. You can use the Nest CLI or manually create the module files.
1nest g module special
Step 2: Create SpecialController and SpecialService
Next, create a controller and service for SpecialModule.
1nest g controller special2nest g service special
Add a simple route in special.controller.ts
:
1import { Controller, Get } from "@nestjs/common";2import { SpecialService } from "./special.service";3
4@Controller("special")5export class SpecialController {6 constructor(private readonly specialService: SpecialService) {}7
8 @Get()9 getSpecialData() {10 return this.specialService.getSpecialData();11 }12}
Add a simple method in special.service.ts
:
1import { Injectable } from "@nestjs/common";2
3@Injectable()4export class SpecialService {5 getSpecialData() {6 return { message: "Special data" };7 }8}
Step 3: Modify AppModule to Include SpecialModule
Ensure that AppModule
includes SpecialModule
:
1import { Module } from "@nestjs/common";2import { SpecialModule } from "./special/special.module";3
4@Module({5 imports: [SpecialModule],6 controllers: [],7 providers: [],8})9export class AppModule {}
Step 4: Create Global Interceptors, Filters, and Guards
Create global interceptors, filters, and guards, and add logic to skip the routes of SpecialModule.
Create a Global Interceptor
1import {2 Injectable,3 NestInterceptor,4 ExecutionContext,5 CallHandler,6} from "@nestjs/common";7import { Observable } from "rxjs";8import { tap } from "rxjs/operators";9
10@Injectable()11export class GlobalInterceptor implements NestInterceptor {12 intercept(context: ExecutionContext, next: CallHandler): Observable<any> {13 const controller = context.getClass();14 const controllerName = controller.name;15
16 // Check if it belongs to SpecialController17 if (controllerName === "SpecialController") {18 return next.handle();19 }20
21 // Execute global interceptor logic22 return next23 .handle()24 .pipe25 // ... Add your global logic here26 ();27 }28}
Create a Global Filter
1import {2 ExceptionFilter,3 Catch,4 ArgumentsHost,5 HttpException,6} from "@nestjs/common";7import { Request, Response } from "express";8
9@Catch(HttpException)10export class GlobalFilter implements ExceptionFilter {11 catch(exception: HttpException, host: ArgumentsHost) {12 const ctx = host.switchToHttp();13 const request = ctx.getRequest<Request>();14 const response = ctx.getResponse<Response>();15 const status = exception.getStatus();16
17 const controller = host.getArgByIndex(1).constructor.name;18
19 // Check if it belongs to SpecialController20 if (controller === "SpecialController") {21 return response.status(exception.getStatus()).json({22 statusCode: status,23 message: exception.message,24 });25 }26
27 // Execute global filter logic28 response.status(status).json({29 statusCode: status,30 timestamp: new Date().toISOString(),31 path: request.url,32 });33 }34}
Create a Global Guard
1import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";2import { Observable } from "rxjs";3
4@Injectable()5export class GlobalGuard implements CanActivate {6 canActivate(7 context: ExecutionContext,8 ): boolean | Promise<boolean> | Observable<boolean> {9 const controller = context.getClass();10 const controllerName = controller.name;11
12 // Check if it belongs to SpecialController13 if (controllerName === "SpecialController") {14 return true;15 }16
17 // Execute global guard logic18 // ... Add your global logic here19 return true;20 }21}
Step 5: Apply Global Interceptors, Filters, and Guards in the Main Application
Register global interceptors, filters, and guards in main.ts
:
1import { NestFactory } from "@nestjs/core";2import { AppModule } from "./app.module";3import { GlobalInterceptor } from "./global.interceptor";4import { GlobalFilter } from "./global.filter";5import { GlobalGuard } from "./global.guard";6
7async function bootstrap() {8 const app = await NestFactory.create(AppModule);9 app.useGlobalInterceptors(new GlobalInterceptor());10 app.useGlobalFilters(new GlobalFilter());11 app.useGlobalGuards(new GlobalGuard());12 await app.listen(3000);13}14bootstrap();
With these modifications, the SpecialController
in SpecialModule
will not be affected by the global interceptors, filters, and guards. Other routes will continue to be processed by the global interceptors, filters, and guards.
Conclusion
By following the above steps, we successfully created a special SpecialModule
and added logic to the global interceptors, filters, and guards to bypass the routes of SpecialModule
. We hope this article helps you implement this feature in your NestJS project.