NestJS中如何在Swagger用DTO生成不同用户类型的API示例?
问题
我正在使用NestJS构建一个更新API并进行文档化,该API针对不同类型用户对应不同属性(部分属性为所有用户通用)。我希望将这些DTO用作不同用户类型的API请求示例,但尝试以下代码后,Swagger UI显示空对象而非DTO定义的属性:
示例代码:
export const updateDirectoryExample = Object.freeze({ sample_1: { summary: 'Contractor', value: { ...new UpdateDirectoryContractorDto() }, }, });
控制器代码:
@ApiOkResponse({ type: UpdateDirectoryResDto, }) @ApiBody({ type: UpdateDirectoryDto, examples: updateDirectoryExample, }) updateDirectory( @AuthUser() reqUserDetails: IRequestUserDetails, @Body() body: UpdateDirectoryDto, @Req() request: Request, ) { return this.directoryService.updateDirectory(reqUserDetails, body, request); }
解决方案
出现空对象的核心原因是:直接实例化DTO类并展开后,类的属性默认未赋值(为undefined),展开操作会自动忽略undefined属性,导致Swagger接收到空对象。以下是几种可行的解决方法:
手动编写示例对象
直接按照DTO的结构手动填充示例值,确保每个需要展示的属性都有对应内容:export const updateDirectoryExample = Object.freeze({ sample_1: { summary: 'Contractor', value: { id: 'DIR-001', fullName: 'Mike Taylor', contractorLicense: 'LIC-12345', // 补充其他通用/专属属性 }, }, });利用DTO的@ApiProperty示例配置
先在DTO的每个属性上通过@ApiProperty的example参数定义示例值,再通过反射提取这些值生成示例对象:- 配置DTO的Swagger属性:
import { ApiProperty } from '@nestjs/swagger'; export class UpdateDirectoryContractorDto { @ApiProperty({ example: 'DIR-001' }) id: string; @ApiProperty({ example: 'Mike Taylor' }) fullName: string; @ApiProperty({ example: 'LIC-12345' }) contractorLicense: string; }- 提取示例值生成示例对象:
import { Reflector } from '@nestjs/core'; const reflector = new Reflector(); export const updateDirectoryExample = Object.freeze({ sample_1: { summary: 'Contractor', value: Object.fromEntries( Object.getOwnPropertyNames(new UpdateDirectoryContractorDto()).map(key => [ key, reflector.get('swagger/apiProperty', UpdateDirectoryContractorDto.prototype, key)?.example ]) ), }, });引用DTO Schema作为示例
如果不需要具体示例值,仅需展示属性结构,可以通过getSchemaPath引用DTO的Swagger Schema:import { getSchemaPath } from '@nestjs/swagger'; export const updateDirectoryExample = Object.freeze({ sample_1: { summary: 'Contractor', value: { $ref: getSchemaPath(UpdateDirectoryContractorDto) }, }, });这种方式会让Swagger直接展示DTO的完整属性结构,而非具体值。
内容的提问来源于stack exchange,提问作者Mitul Kheni
相关产品推荐
相关产品推荐

