推荐答案
NestJS 的拦截器(Interceptors)是一种强大的机制,允许你在请求处理过程中插入自定义逻辑。拦截器可以在方法执行前后执行额外的操作,例如日志记录、异常处理、数据转换等。它们通常用于实现横切关注点(cross-cutting concerns),如日志记录、缓存、性能监控等。
创建拦截器
要创建一个拦截器,你需要实现 NestInterceptor 接口,并使用 @Injectable() 装饰器将其标记为可注入的服务。拦截器的主要方法是 intercept,它接收两个参数:context(执行上下文)和 next(调用链中的下一个处理程序)。
// 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`)),
);
}
}使用拦截器
拦截器可以通过多种方式使用,最常见的方式是在控制器或全局范围内应用它们。
在控制器中使用拦截器
你可以通过在控制器或路由处理程序上使用 @UseInterceptors() 装饰器来应用拦截器。
// 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';
}
}全局使用拦截器
你还可以在应用程序的全局范围内应用拦截器,这样它会影响所有的路由。
// 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();本题详细解读
拦截器的概念
拦截器是 NestJS 中的一个核心概念,它允许你在请求处理的不同阶段插入自定义逻辑。拦截器的主要作用是在方法执行前后执行额外的操作,例如日志记录、异常处理、数据转换等。它们通常用于实现横切关注点(cross-cutting concerns),如日志记录、缓存、性能监控等。
拦截器的实现
拦截器通过实现 NestInterceptor 接口来创建。intercept 方法是拦截器的核心,它接收两个参数:context 和 next。context 提供了当前执行上下文的信息,而 next 是一个可调用对象,用于继续处理请求。
拦截器的使用场景
拦截器可以用于多种场景,例如:
- 日志记录:在请求处理前后记录日志。
- 性能监控:测量请求处理的时间。
- 数据转换:在返回响应之前对数据进行转换。
- 异常处理:捕获并处理请求处理过程中抛出的异常。
拦截器的应用方式
拦截器可以通过以下方式应用:
- 控制器级别:在控制器或路由处理程序上使用
@UseInterceptors()装饰器。 - 全局级别:在应用程序的全局范围内使用
app.useGlobalInterceptors()方法。
拦截器的执行顺序
拦截器的执行顺序与它们在代码中的声明顺序一致。多个拦截器可以串联使用,每个拦截器都可以在请求处理的不同阶段执行自定义逻辑。
拦截器的优势
使用拦截器的主要优势在于它们提供了一种干净、模块化的方式来处理横切关注点。通过将通用逻辑封装在拦截器中,你可以避免在多个地方重复相同的代码,从而提高代码的可维护性和可读性。