node 框架 Nest.js 简单实现请求结果统一返回数据格式

简单实现请求结果统一返回数据格式

前言

在设计路由回调时返回格式时,会考虑到怎么把所有接口的成功和失败怎么统一起来。现在我们来根据 Nest 给出的 异常过滤器拦截器 API 来实现一下

贴出跟进看的文档以方便大家进一步学习 Nest 中文文档


异常过滤器

  • Nest 内置的 异常层 负责处理整个应用程序中的所有抛出的异常。当捕获到未处理的异常时,最终用户将收到友好的响应。

  • 这里可理解为当我们系统发生异常到响应给用户的一个中间层。

image.png

 ### 实现
复制代码
  • 异常过滤代码

    /* all-exception.filter.ts */
    
    // 引入所需内置对象
    import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
    import * as moment from 'moment';
    
    // 们需要访问底层平台 `Request`和 `Response`
    import { Request, Response } from 'express';
    
    // 它负责捕获作为`HttpException`类实例
    @Catch(HttpException)
    export class HttpExceptionFilter implements ExceptionFilter {
      catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();
        const request = ctx.getRequest<Request>();
        const status = exception.getStatus();
        // 用于接收主动发错的错误信息 
        const { message, code } = exception.getResponse() as any;
        response.status(status).json({
          code: code || status,
          timestamp: moment().format('yyyy-MM-DD HH:mm:ss'),
          path: request.url,
          error: 'Bad Request',
          message,
        });
      }
    }
    
    复制代码
  • mian.ts 文件中引用,并注册

      /* main.ts */
    import { HttpExceptionFilter } from './filters/http-exception.filter';
    async function bootstrap() {
     ...
     // 全局注册错误的过滤器
     app.useGlobalFilters(new HttpExceptionFilter());
    }
    bootstrap();
    复制代码
  • 在其他文件中主动触发请求失败

      /* 使用 */
       import { HttpException } from '@nestjs/common';
       // 主动处罚异常
       throw new HttpException('请求失败', 500);
    复制代码

    效果

    • 这里是在 JWT 中做了判断处理主动触发了 token 过期事件,当然也可以在 service controller ..等数据处理中触发

拦截器

  • 拦截器是使用 @Injectable() 装饰器注解的类。拦截器应该实现 NestInterceptor 接口。

  • 拦截器具有一系列有用的功能,这些功能受面向切面编程(AOP)技术的启发。它们可以: 在函数执行之前/之后绑定额外的逻辑 , 转换 从函数返回的结果 ,转换从函数抛出的异常 ,扩展 基本函数行为 , 根据所选条件完全重写函数 (例如, 缓存目的)

  • 这里我们使用拦截器做一个 请求响应的数据拦截 transformr.interceptor 这样不用再每个 service 下做重复的返回格式处理

image.png

 ### 实现
复制代码
  • 拦截器代码

    /* transform.interceptor.ts */
    
    import { Injectable, NestInterceptor, CallHandler, ExecutionContext } from '@nestjs/common';
    import { map } from 'rxjs/operators';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class TransformInterceptor implements NestInterceptor {
      intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        return next.handle().pipe(
          map((data) => {
            return {
              data,
              code: 200,
              message: '请求成功',
            };
          }),
        );
      }
    }
    
    复制代码
  • mian.ts 文件中引用,并注册

      /* main.ts */
     ...
    import { TransformInterceptor } from './interceptor/transform.interceptor';
    async function bootstrap() {
     ...
     // 全局注册拦截器
     app.useGlobalInterceptors(new TransformInterceptor());
     ...
    }
    bootstrap();
    
    复制代码
  • 使用只要在路由中 retrun 出去即可

    效果

  • image.png

总结

  • 至此我们已经完成在 Nest.js 中对请求返回的信息做了基础的封装 。
  • 想要知道更多 拦截器 玩法的同学可以去官方文档中查阅 文档

参考文献

猜你喜欢

转载自juejin.im/post/7067071461998985229