You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS中实现全局统一自定义响应格式?

在NestJS中实现统一自定义响应格式

要实现你需要的统一响应格式,核心是利用NestJS的拦截器(处理成功响应)和异常过滤器(处理异常响应),全局注册后即可对所有控制器的请求生效。

一、实现成功响应拦截器

拦截器可以在控制器返回结果后,统一包装成你需要的格式。创建一个TransformInterceptor:

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // 获取当前请求的URL和方法
    const request = context.switchToHttp().getRequest();
    const requestInfo = {
      url: request.url,
      method: request.method,
    };

    // 包装响应数据
    return next.handle().pipe(
      map((data) => ({
        status: 'success',
        code: 200, // 可根据业务需求替换为自定义业务码
        message: '请求成功', // 支持从控制器返回值中动态读取,比如data.message
        data: data,
        request: requestInfo,
      })),
    );
  }
}

如果需要动态设置message,可以让控制器返回包含message和data的对象,然后修改拦截器的map逻辑:

map((response) => ({
  status: 'success',
  code: 200,
  message: response.message || '请求成功',
  data: response.data || response,
  request: requestInfo,
})),

二、实现全局异常过滤器

异常过滤器捕获所有未处理的异常,统一包装成你需要的异常响应格式。创建AllExceptionsFilter:

import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch() // 捕获所有类型的异常
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    // 区分HTTP异常和未知异常
    const status = exception instanceof HttpException 
      ? exception.getStatus() 
      : HttpStatus.INTERNAL_SERVER_ERROR;
    const message = exception instanceof HttpException
      ? (exception.getResponse() as any).message || exception.message
      : '服务器内部错误';
    const error = exception instanceof HttpException
      ? exception.getResponse() || exception
      : exception;

    // 返回统一格式的异常响应
    response.status(status).json({
      status: 'error',
      code: status, // 可替换为自定义业务错误码
      message: message,
      error: error,
      request: {
        url: request.url,
        method: request.method,
      },
    });
  }
}

三、全局注册拦截器和过滤器

有两种方式可以全局注册,任选其一即可:

方式1:在main.ts中直接注册

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { TransformInterceptor } from './interceptors/transform.interceptor';
import { AllExceptionsFilter } from './filters/all-exceptions.filter';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  
  // 注册全局拦截器和异常过滤器
  app.useGlobalInterceptors(new TransformInterceptor());
  app.useGlobalFilters(new AllExceptionsFilter());
  
  await app.listen(3000);
}
bootstrap();

方式2:在模块中通过依赖注入注册

适合需要注入其他服务到拦截器/过滤器的场景,以AppModule为例:

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR, APP_FILTER } from '@nestjs/core';
import { TransformInterceptor } from './interceptors/transform.interceptor';
import { AllExceptionsFilter } from './filters/all-exceptions.filter';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: TransformInterceptor,
    },
    {
      provide: APP_FILTER,
      useClass: AllExceptionsFilter,
    },
  ],
})
export class AppModule {}

四、自定义扩展说明

  • 业务码替换:可以将code字段替换为你的自定义业务状态码,比如在异常过滤器中读取自定义异常的业务码,或者在拦截器中根据业务场景设置不同的成功码。
  • 异常细分处理:如果需要针对特定类型的异常(比如自定义业务异常)做特殊处理,可以在AllExceptionsFilter中添加条件判断,单独处理该异常的code和message。

内容的提问来源于stack exchange,提问作者Pandhu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 06:50:27