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

NestJS/Swagger中如何根据所选Media type配置不同请求体Schema

NestJS Swagger 多MediaType对应独立请求Schema配置方法

NestJS Swagger模块原生支持直接配置不同请求媒体类型对应的独立Schema,不需要魔改源码,按下面步骤配置即可:

前置准备

先定义好两种媒体类型对应的请求DTO,用常规的@ApiProperty装饰器标记字段即可,Swagger会自动生成对应的Schema定义:

// src/face/dto/face.dto.ts
import { ApiProperty } from '@nestjs/swagger';

// application/json 对应请求结构
export class FaceEnrollmentRequest {
  @ApiProperty({ description: '人脸图片Base64字符串' })
  imageBase64: string;

  @ApiProperty({ description: '用户唯一标识' })
  userId: string;
}

// multipart/form-data 对应请求结构
export class FaceEnrollmentRequestMultipart {
  @ApiProperty({ type: 'string', format: 'binary', description: '人脸图片文件' })
  file: Express.Multer.File;

  @ApiProperty({ description: '用户唯一标识' })
  userId: string;
}

核心配置

在对应的控制器接口方法上,通过@ApiConsumes声明接口支持的媒体类型,再通过@ApiBody的content字段手动绑定每个媒体类型对应的Schema引用即可:

// src/face/face.controller.ts
import { Controller, Post, Body, UseInterceptors, UploadedFile } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiBody, ApiConsumes, getSchemaPath } from '@nestjs/swagger';
import { FaceEnrollmentRequest, FaceEnrollmentRequestMultipart } from './dto/face.dto';

@Controller('face')
export class FaceController {
  @Post('enrollment')
  @UseInterceptors(FileInterceptor('file'))
  // 声明接口支持的两种请求媒体类型
  @ApiConsumes('application/json', 'multipart/form-data')
  // 绑定不同媒体类型对应的Schema
  @ApiBody({
    content: {
      'application/json': {
        schema: { $ref: getSchemaPath(FaceEnrollmentRequest) }
      },
      'multipart/form-data': {
        schema: { $ref: getSchemaPath(FaceEnrollmentRequestMultipart) }
      }
    }
  })
  async faceEnrollment(
    @Body() jsonBody: FaceEnrollmentRequest,
    @UploadedFile() file?: Express.Multer.File
  ) {
    // 业务逻辑里自行根据Content-Type判断处理两种请求格式即可
    return { code: 0, msg: '录入成功' };
  }
}

注意事项

如果你的DTO没有被@Body()这类参数装饰器直接作为类型引用,Swagger不会自动扫描生成对应的Schema,需要在初始化Swagger文档时把DTO加入额外模型列表:

// src/main.ts
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { FaceEnrollmentRequest, FaceEnrollmentRequestMultipart } from './face/dto/face.dto';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const swaggerConfig = new DocumentBuilder()
    .setTitle('人脸服务接口文档')
    .setVersion('1.0')
    .build();
  const swaggerDocument = SwaggerModule.createDocument(app, swaggerConfig, {
    // 加入未被直接引用的DTO,保证Schema能正常生成
    extraModels: [FaceEnrollmentRequest, FaceEnrollmentRequestMultipart]
  });
  SwaggerModule.setup('api/docs', app, swaggerDocument);

  await app.listen(3000);
}
bootstrap();

配置完成后生成的OpenAPI结构和预期完全一致,Swagger UI中切换Media type下拉选项时,会自动切换对应的请求体Schema、示例和表单控件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:18:15