在NestJS中,如何實現一個module避開全局的Interceptors,Filters和Guards

在開發 NestJS 應用程序時,有時我們需要某些模塊(例如 SpecialModule)避開全局的攔截器(useGlobalInterceptors)、過濾器(useGlobalFilters)和守衛(useGlobalGuards)。本文將介紹如何在 NestJS 中實現一個特殊的 SpecialModule,通過在全局攔截器、過濾器和守衛中手動添加邏輯來跳過 SpecialModule 的路由。

步驟一:創建 SpecialModule

首先,我們創建一個 SpecialModule。你可以使用 Nest CLI 或手動創建模塊文件。

Terminal window
1
nest g module special

步驟二:創建 SpecialController 和 SpecialService

接下來,為 SpecialModule 創建控制器和服務。

Terminal window
1
nest g controller special
2
nest g service special

special.controller.ts 中添加一個簡單的路由:

1
import { Controller, Get } from "@nestjs/common";
2
import { SpecialService } from "./special.service";
3
4
@Controller("special")
5
export class SpecialController {
6
constructor(private readonly specialService: SpecialService) {}
7
8
@Get()
9
getSpecialData() {
10
return this.specialService.getSpecialData();
11
}
12
}

special.service.ts 中添加一個簡單的方法:

1
import { Injectable } from "@nestjs/common";
2
3
@Injectable()
4
export class SpecialService {
5
getSpecialData() {
6
return { message: "Special data" };
7
}
8
}

步驟三:修改 AppModule 以包含 SpecialModule

確保 AppModule 包含 SpecialModule

1
import { Module } from "@nestjs/common";
2
import { SpecialModule } from "./special/special.module";
3
4
@Module({
5
imports: [SpecialModule],
6
controllers: [],
7
providers: [],
8
})
9
export class AppModule {}

步驟四:創建全局攔截器、過濾器和守衛

創建全局攔截器、過濾器和守衛,添加邏輯以跳過 SpecialModule 的路由。

創建全局攔截器

1
import {
2
Injectable,
3
NestInterceptor,
4
ExecutionContext,
5
CallHandler,
6
} from "@nestjs/common";
7
import { Observable } from "rxjs";
8
import { tap } from "rxjs/operators";
9
10
@Injectable()
11
export class GlobalInterceptor implements NestInterceptor {
12
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
13
const controller = context.getClass();
14
const controllerName = controller.name;
15
16
// 檢查是否屬於 SpecialController 控制器
17
if (controllerName === "SpecialController") {
18
return next.handle();
19
}
20
21
// 執行全局攔截器邏輯
22
return next
23
.handle()
24
.pipe
25
// ... 在這裡加入你的全局邏輯
26
();
27
}
28
}

創建全局過濾器

1
import {
2
ExceptionFilter,
3
Catch,
4
ArgumentsHost,
5
HttpException,
6
} from "@nestjs/common";
7
import { Request, Response } from "express";
8
9
@Catch(HttpException)
10
export 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
// 檢查是否屬於 SpecialController 控制器
20
if (controller === "SpecialController") {
21
return response.status(exception.getStatus()).json({
22
statusCode: status,
23
message: exception.message,
24
});
25
}
26
27
// 執行全局過濾器邏輯
28
response.status(status).json({
29
statusCode: status,
30
timestamp: new Date().toISOString(),
31
path: request.url,
32
});
33
}
34
}

創建全局守衛

1
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
2
import { Observable } from "rxjs";
3
4
@Injectable()
5
export 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
// 檢查是否屬於 SpecialController 控制器
13
if (controllerName === "SpecialController") {
14
return true;
15
}
16
17
// 執行全局守衛邏輯
18
// ... 在這裡加入你的全局邏輯
19
return true;
20
}
21
}

步驟五:在主應用程序中應用全局攔截器、過濾器和守衛

main.ts 中註冊全局攔截器、過濾器和守衛:

1
import { NestFactory } from "@nestjs/core";
2
import { AppModule } from "./app.module";
3
import { GlobalInterceptor } from "./global.interceptor";
4
import { GlobalFilter } from "./global.filter";
5
import { GlobalGuard } from "./global.guard";
6
7
async 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
}
14
bootstrap();

通過這些修改,SpecialModule中的SpecialController將不會被全局攔截器、過濾器和守衛所影響。其他路由將繼續被全局攔截器、過濾器和守衛處理。

結論

通過以上步驟,我們成功創建了一個特殊的 SpecialModule,並在全局攔截器、過濾器和守衛中添加了邏輯,使其能夠跳過 SpecialModule 的路由。希望這篇文章對你在 NestJS 項目中的實現有所幫助。