推荐答案
在 Nest.js 中,创建拦截器可以通过以下步骤实现:
- 创建拦截器类:使用
@Injectable()装饰器定义一个类,并实现NestInterceptor接口。 - 实现
intercept方法:在拦截器类中实现intercept方法,该方法接收两个参数:ExecutionContext和CallHandler。 - 使用
CallHandler:在intercept方法中调用CallHandler的handle()方法,以继续执行后续的请求处理流程。 - 应用拦截器:可以通过装饰器
@UseInterceptors()将拦截器应用到控制器或路由处理程序上。
示例代码:
// www.javascriptcn.com code example
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
const now = Date.now();
return next
.handle()
.pipe(
tap(() => console.log(`After... ${Date.now() - now}ms`)),
);
}
}在控制器或路由处理程序上应用拦截器:
// www.javascriptcn.com code example
import { Controller, Get, UseInterceptors } from '@nestjs/common';
import { LoggingInterceptor } from './logging.interceptor';
@Controller('cats')
@UseInterceptors(LoggingInterceptor)
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}本题详细解读
拦截器的作用
拦截器是 Nest.js 中的一种高级功能,允许你在请求处理的不同阶段插入自定义逻辑。拦截器可以用于以下场景:
- 日志记录:在请求处理前后记录日志。
- 性能监控:测量请求处理时间。
- 数据转换:在请求处理前后对数据进行转换。
- 异常处理:在请求处理过程中捕获并处理异常。
拦截器的生命周期
拦截器的生命周期主要分为两个阶段:
- 请求处理前:在请求到达控制器之前,拦截器可以执行一些预处理操作,例如记录日志、验证请求数据等。
- 请求处理后:在控制器处理完请求后,拦截器可以执行一些后处理操作,例如记录响应时间、转换响应数据等。
拦截器的实现细节
在实现拦截器时,intercept 方法是核心。该方法接收两个参数:
ExecutionContext:提供了当前请求的上下文信息,例如请求对象、响应对象、路由信息等。CallHandler:用于调用后续的请求处理流程。通过调用handle()方法,可以继续执行后续的中间件、管道、控制器等。
在 intercept 方法中,你可以使用 RxJS 的操作符(如 tap、map 等)来处理请求和响应数据。
拦截器的应用
拦截器可以通过 @UseInterceptors() 装饰器应用到控制器或路由处理程序上。你可以将拦截器应用到整个控制器,也可以应用到特定的路由处理程序上。
此外,拦截器还可以全局应用,通过 app.useGlobalInterceptors() 方法将拦截器应用到整个应用程序中。
// www.javascriptcn.com code example
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { LoggingInterceptor } from './logging.interceptor';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());
await app.listen(3000);
}
bootstrap();通过全局应用拦截器,你可以在整个应用程序中统一处理请求和响应逻辑。