1. 实现统一响应返回
拦截器具有一系列有用的功能,这些功能受面向切面编程(AOP)技术的启发。它们可以:
- 在函数执行之前/之后绑定额外的逻辑
- 转换从函数返回的结果
- 转换从函数抛出的异常
- 扩展基本函数行为
- 根据所选条件完全重写函数 (例如, 缓存目的)
我们现在没有给我们的Nestjs 规范返回给前端的格式现在比较乱,
我们可以通过 @nestjs/common 包中的 @Injectable() 装饰器和 @nestjs/common 包中的 NestInterceptor 接口类类实现自定义的响应拦截器。
{
data, //数据
status:0,
message:"成功",
success:true
}
新建common 文件夹 创建 response.ts
import { Injectable, NestInterceptor, CallHandler } from '@nestjs/common'
import { map } from 'rxjs/operators'
import {Observable} from 'rxjs'
interface data<T>{
data:T
}
@Injectable()
export class Response<T = any> implements NestInterceptor {
intercept(context, next: CallHandler):Observable<data<T>> {
return next.handle().pipe(map(data => {
return {
data,
status:0,
success:true,
message:"成功"
}
}))
}
}
上述代码中的 ResponseInterceptor 是一个用于统一响应结果的响应拦截器,通过 map() 运算符改变响应结果格式,并在结果中添加固定的格式。
使用方式
- 在main.ts 全局注册
import { Response } from './common/response';
app.useGlobalInterceptors(new Response())
- 单个接口注册
app.controller.ts
import { Controller, Get, Inject, UseInterceptors } from '@nestjs/common';
import { AppService } from './app.service';
import { Response } from './common/response';
import { UserService } from './user/user.service';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly userService: UserService,
) {}
@Get()
@UseInterceptors(Response)
getHello(): object {
return this.value;
}
@Get('user')
getUser(): string {
return this.userService.findAll();
}
}
这样就可以针对单个接口做响应返回
2. 实现异常拦截器
方式同上
common中新建一个 filter.ts
import {
Catch,
ExceptionFilter,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
const status = exception.getStatus();
response.status(status).json({
data: exception.message,
time: new Date().getTime(),
success: false,
path: request.url,
status,
});
}
}
使用
- main.ts 引入全局使用
import { NestFactory } from '@nestjs/core';
// import { NextFunction, Response, Request } from 'express';
import { AppModule } from './app.module';
import { Response } from './common/response';
import { HttpFilter } from './common/filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new Response());
app.useGlobalFilters(new HttpFilter());
await app.listen(3000);
}
bootstrap();
请求http://localhost:3000/upload/1/123/123 不存在的地址
- 单个接口使用
直接传入类即可,不需要调用
import {
Controller,
Get,
Inject,
UseInterceptors,
UseFilters,
NotFoundException,
} from '@nestjs/common';
import { AppService } from './app.service';
import { Response } from './common/response';
import { UserService } from './user/user.service';
import { HttpFilter } from './common/filter';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly userService: UserService,
) {}
@Get()
@UseInterceptors(Response)
@UseFilters(HttpFilter)
getHello(): object {
throw new NotFoundException('111');
}
@Get('user')
getUser(): string {
return this.userService.findAll();
}
}
上述代码中,NotFoundException 是 Nest.js 中的一个针对 HTTP 请求状态码为 404 的异常,这里我们可以使用 HttpExcepionFilter 拦截它,并返回自定义的错误信息。