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
相关产品推荐
相关产品推荐

