拦截器是使用 @Injectable() 装饰器注解的类。拦截器应该实现 NestInterceptor 接口
创建拦截器
执行$ nest g interceptor userInterceptor,创建一个名为 userInterceptor 的拦截器
$ nest g interceptor userInterceptor
创建一个拦截器实例
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
// 定义了一个名为TransformInterceptor的拦截器,该拦截器实现了NestInterceptor接口,并使用了泛型T和Response
export class LoggingInterceptor implements NestInterceptor {
// 实现了NestInterceptor接口中的intercept方法,该方法接收两个参数:执行上下文 和 调用处理程序
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
const now = Date.now();
// 通过调用next.handle()方法获取到调用处理程序返回的数据
return next
.handle()
.pipe(
tap(() => console.log(`After... ${Date.now() - now}ms`)),
);
}
}
注入器(Injectable)
拦截器(NestInterceptor)
执行上下文(ExecutionContext)
调用处理程序(CallHandler)
绑定拦截器
方法一:类型绑定
@Get()
// 传递的型
@UseInterceptors(LoggingInterceptor)
export class CatsController {}
方法二:实例绑定
@Get()
// 传递实例
@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
全局拦截器
全局拦截器绑定在主模块中
const app = await NestFactory.create(ApplicationModule);
app.useGlobalInterceptors(new LoggingInterceptor());
响应映射
该拦截器的作用是将响应数据封装为一个标准的Response对象,并返回给客户端。
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Response<T> {
data: T;
}
@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
return next.handle().pipe(map(data => ({ data })));
}
}
假设我们需要将每个发生的 null 值转换为空字符串 ''
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(map(value => value === null ? '' : value ));
}
}
异常映射
import {
Injectable,
NestInterceptor,
ExecutionContext,
BadGatewayException,
CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(
catchError(err => throwError(new BadGatewayException())),
);
}
}
实例:
假设要处理路由请求超时。如果端点在一段时间后未返回任何内容,则将以错误响应终止。
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';
@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
timeout(5000),
catchError(err => {
if (err instanceof TimeoutError) {
return throwError(new RequestTimeoutException());
}
return throwError(err);
}),
);
};
};