Nest核心组件 - 拦截器 Interceptors

7/10/2023 NodejsNestjs

# 2.8 拦截器(Interceptors)

拦截器在 NestJS 中用于对请求、响应和异常进行全局的处理。它可以在请求到达控制器之前或响应离开控制器之后对它们进行拦截。

# 2.8.1 创建一个拦截器

让我们来创建一个简单的拦截器。在 src 目录下创建一个新的文件 logging.interceptor.ts,并编写以下代码:

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`))
      );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

在上面的代码中,我们创建了一个实现了 NestInterceptor 接口的拦截器类 LoggingInterceptor。NestInterceptor 接口要求拦截器类实现 intercept 方法,该方法将在请求到达控制器之前或响应离开控制器之后被调用。

在 intercept 方法中,我们可以访问 ExecutionContext 对象,并从中获取请求和响应对象。在这个例子中,我们简单地在请求到达控制器之前打印 "Before...",在响应离开控制器之后打印 "After...",并输出请求处理的时间。

# 2.8.2 使用拦截器

现在我们已经创建了一个简单的拦截器 LoggingInterceptor,接下来我们需要在应用程序中使用它。

要使用拦截器,我们可以通过 @UseInterceptors() 装饰器将其应用于控制器中的特定路由或全局路由。在这里我们将它应用于一个特定的控制器路由示例。

打开 cats.controller.ts 文件,并将 LoggingInterceptor 应用于 findAll 方法:

import { Controller, Get, Post, Body, UsePipes, UseGuards, UseInterceptors } from '@nestjs/common';
import { CatsService } from './cats.service';
import { CreateCatDto } from './dto/create-cat.dto';
import { ValidationPipe } from '../validation.pipe';
import { RolesGuard } from '../roles.guard';
import { LoggingInterceptor } from '../logging.interceptor';

@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Post()
  @UsePipes(ValidationPipe)
  @UseGuards(RolesGuard)
  @UseInterceptors(LoggingInterceptor)
  create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto.name);
  }

  @Get()
  findAll(): string[] {
    return this.catsService.findAll();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

在上面的代码中,我们在 findAll 方法上使用了 @UseInterceptors(LoggingInterceptor) 装饰器,将 LoggingInterceptor 应用于 findAll 方法。这样,当请求到达 findAll 方法时,LoggingInterceptor 将在请求到达控制器之前打印 "Before...",在响应离开控制器之后打印 "After...",并输出请求处理的时间。

当我们发送 GET 请求到 /cats 路径时,findAll 方法会被调用,而在调用之前和之后,LoggingInterceptor 将分别打印 "Before..." 和 "After..."。

# 总结

在本章中,我们深入了解了 NestJS 的基本概念和核心组件,包括控制器、提供者、模块、中间件、异常过滤器、管道、守卫和拦截器。这些组件是构建 NestJS 应用程序的基础,了解它们的作用和用法对于后续的开发至关重要。

编辑时间: 7/10/2023, 10:00:00 AM