在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 项目中的实现有所帮助。

美团外卖红包 饿了么红包 支付宝红包