NestJS——响应结果统一处理

对于响应结果统一处理,顾名思义,就是后端返回的数据结果包装成一个统一的对象返回到前端。也就是下面这种格式👇

ts 复制代码
// 成功时返回
{
    data, // data即我们返回的数据
    // 以下字段均可自定义,也可自行添加删除字段
    code: 0, 
    message: "成功",
    success: true
}

// 接口异常时返回
{
    // 以下字段均可自定义,也可自行添加删除字段
    success: false,
    time: new Date(),
    msg: exception.message,
    status,
    path: request.url,
}

接着我创建ResponseModule,ResponseController,ResponseService模块,我这里就手动创建了,你也可以使用nest g res xxx命令来创建,然后在ResponseModule中引入ResponseController和ResponseService。具体如下👇

对应代码:

ResponseModule.ts

ts 复制代码
import { Module } from '@nestjs/common';
import { ResponseController } from 'src/controller/ResponseController';
import { ResponseService } from 'src/service/ResponseService';

@Module({
  controllers: [ResponseController],
  providers: [ResponseService],
})
export class ResponseModule {}

ResponseController.ts

ts 复制代码
import { Controller } from '@nestjs/common';

@Controller('res')
export class ResponseController {}

ResponseService.ts

ts 复制代码
import { Injectable } from '@nestjs/common';

@Injectable()
export class ResponseService {}

然后我们将ResponseModule.ts引入到app.module.ts

ts 复制代码
import {Module} from '@nestjs/common';
import {AppController} from "./app.controller";
import {AppService} from "./app.service";
import { ResponseModule } from './modules/ResponseModule';

@Module({
    // 注入模块
    imports: [
        ResponseModule,
    ],
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule {}

接着我们先测试一下接口能不能通,我这里就直接在ResponseController.ts中写个test方法来测试了。

ts 复制代码
import { Controller, Get } from '@nestjs/common';

@Controller('res')
export class ResponseController {
  @Get()
  test() {
    return '接口通过';
  }
}

非常顺序,接口进入主题。我们去封装一个统一的响应格式,我创建SuccessResponse.ts,创建类SuccessResponse去实现Nest内置的NestInterceptor接口,该接口需要实现intercept方法

SuccessResponse.ts

ts 复制代码
import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor,
} from '@nestjs/common';
import { Observable, map } from 'rxjs';

interface Data<T> {
  data: T;
}

@Injectable()
export class SuccessResponse<T> implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Data<T>> {
    return next.handle().pipe(
      map((data) => {
        return {
          data, // data即为 Service层或者Controller层的返回值
          code: 0,
          message: '请求成功',
          success: true,
        };
      }),
    );
  }
}

接着在main.ts去使用

然后我们在ResponseController.ts 和 ResponseService.ts 写一下返回逻辑

ResponseController.ts

ts 复制代码
import { ResponseService } from './../service/ResponseService';
import { Controller, Get } from '@nestjs/common';

@Controller('res')
export class ResponseController {
  constructor(private readonly responseService: ResponseService) {}
  @Get()
  test() {
    return this.responseService.test();
  }
}

ResponseService.ts

ts 复制代码
import { Injectable } from '@nestjs/common';

@Injectable()
export class ResponseService {
  test() {
    return {
      name: 'Lee',
      age: 18,
    };
  }
}

测试一下,返回结果已经包装成我们想要的对象

以上为接口返回成功的情况。下面来说说接口异常的情况,过程其实和以上类似,只是我们更换实现类。 我这里创建HttpFaild.ts去实现Nest内置的ExceptionFilter接口,接口有一个方法catch需要去实现。

HttpFaild.ts代码如下:

ts 复制代码
import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
} from '@nestjs/common';
import { Response, Request } from 'express';

@Catch()
// 接口异常拦截器
export class HttpFaild 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();
    console.log(status, 'status');

    response.status(status).json({
      success: false,
      time: new Date(),
      msg: exception.message,
      status,
      path: request.url,
    });
  }
}

接着去main.ts使用

接着我在ResponseService去模拟异常

接口返回如下:

以上是本次文章内容,欢迎您的收看,喜欢点赞+收藏+关注,如有问题欢迎指正。

相关推荐
kerli4 分钟前
基于 kmp/cmp 的跨平台图片加载方案 - 适配 Android View/Compose/ios
android·前端·ios
JavaGuide11 分钟前
万字详解 RAG 向量索引算法和向量数据库
后端·面试
舒一笑16 分钟前
Docker 离线镜像导入后变成 <none>:<none>?一文讲透原因、排查与正确打包姿势
后端·docker·容器
RONIN19 分钟前
vue组件、组件生命周期、组件分离模块化
前端·vue.js
小强198820 分钟前
HTML5语义化标签:从`div`到`article`与`section`的进化之路
前端
RONIN20 分钟前
vue开发环境与基础语法、计算属性、侦听属性
前端·vue.js
Nyarlathotep011327 分钟前
并发集合类(1):CopyOnWriteArrayList
java·后端
WayneYang27 分钟前
JavaScript ES6+ (ES2015~ES2024) 全特性整理
前端·javascript
逆光如雪28 分钟前
移动端border-left 和 width:1px,同样写1px为什么粗细不同?
前端·css