为啥 dto 中的类型在 swagger 中不可见?

Posted

技术标签:

【中文标题】为啥 dto 中的类型在 swagger 中不可见?【英文标题】:Why are types in dto not visible in swagger?为什么 dto 中的类型在 swagger 中不可见? 【发布时间】:2020-07-12 04:06:18 【问题描述】:

我正在根据此文档在我的小型 Nest.js 应用程序中设置 swagger 文档:https://docs.nestjs.com/recipes/swagger

如何设置 dto 以在 swagger 中正确显示架构?更具体地说,嵌套类型。它仅显示***键。如果其中一个键是某种类型的,它会将其显示为空对象。这就是我的意思:

dto:

export class HealthCheckDataDto 
    serverStatus:  // dont have it typed yet;
    dbStatus: MongoConnectionStateT;
 

大摇大摆:

[
  
    "serverStatus": ,
    "dbStatus": 
  
]

大摇大摆示例值中的预期结果:

[
  
    "serverStatus": ,
    "dbStatus": 
      "isOnline": true,
      "msg": "string"
    
  
]

这是函数:

@ApiResponse( status: 200, description: 'blabla', type: [HealthCheckDataDto] )
@ApiResponse( status: 500, description: 'blabla, but bad', type: [HealthCheckDataDto] )
@Get('/api/healthcheck')
healthCheckApp(@Res() res: Response<HealthCheckDataDto>) 

    // check HCs and setup status code
    const healthCheck: HealthCheckI = this.healthcheckService.getFullHealthCheck();
    const statusCode = (healthCheck.dbStatus.isOnline) ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR;

    // return that response
    res.status(statusCode).json(healthCheck);

我尝试了什么:

当我将类型替换为 dto 中的精确参数时,它会以大摇大摆的方式正确显示。 我对接口进行了 dto 的交叉检查,我在“isOnline”中添加了错误的字段,它找到并标记它,它不好。 Schema 以大摇大摆的方式显示,但也只是***,而不是类型化的部分。所以它不仅仅是示例值。 检查堆栈溢出;找到了两个相关的线程,但没有一个解决它。一位建议手动创建子 dto 而不是类型。嗯……我最好不要那样做。

我做错了什么,或遗漏了文档中的某些内容。或者,在生成 json 时,该 swagger 模块的解析器可能无法提取类型/接口。

【问题讨论】:

【参考方案1】:

我错过了NestJS Documentation: Generics and interfaces的一个位置:

由于 TypeScript 不存储有关泛型或接口的元数据, 当您在 DTO 中使用它们时,SwaggerModule 可能无法 在运行时正确生成模型定义。

嗯,有道理。

在某些特定场景(例如深度嵌套的数组、矩阵)中,您 可能需要手动描述您的类型。

所以,对我有用的最终设置如下

创建不带类型的 DTO,但匹配类型/接口结构,就像在原始问题中的“预期结果”中一样 请求/响应应使用 dto 键入,例如 Result&lt;SomeDto&gt; 当您在该函数中处理数据时,使用 interface/type 键入它,而不是 dto 并且您有交叉检查。

就像这个数据是有效的,swagger 是正确生成的。如需更多招摇信息,请直接在 DTO 中使用装饰器。

【讨论】:

【参考方案2】:

您可以使用 OpenAPI CLI plugin 在 Swagger 中自动显示类型。

添加:

  "compilerOptions": 
    "plugins": ["@nestjs/swagger"]
  

nest-cli.json,并添加:

import  ApiProperty, ApiBody  from '@nestjs/swagger';

到您的每个 DTO,插件将自动注释和记录您的架构!

【讨论】:

嗨 drkvogel 和 @ibrahim-ali-musah 感谢您的回答。我签入了你提到的东西的代码。它已经在那里了。可能是版本问题,因为我在创建该 cli 文档的几个月前制作了这个应用程序,同时在 Nest 及其库上也有主要版本增量。在第一季度,我有计划的应用程序扩展,所以我会升级库和东西,然后再试一次。如果它在没有我的线程答案中提到的所有东西的情况下也能工作,我将不得不用过时的标签更新我的问题。谢谢! @Peter 您可以通过投票来表示感谢! :)【参考方案3】:

根据来自的文档 types and parameters 你只需要使用任何一个

@Body(), @Query(), @Param()

然后,swagger 模块会自动为您填充内容。这还要求您将nest-cli.json 文件更新为


"collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": 
    "plugins": ["@nestjs/swagger/plugin"]
  

那么所有事情都应该为你完成并生成。

请注意,如果这不会自动显示它们或显示架构为空,那么您使用@ApiProperty() 装饰您的 dto 的至少一个条目,然后刷新页面。这样就搞定了。

【讨论】:

以上是关于为啥 dto 中的类型在 swagger 中不可见?的主要内容,如果未能解决你的问题,请参考以下文章

在 Unity 5 中,为啥精灵表中的某些精灵在精灵中不可见,但在 UI 图像中可以正常工作?

为啥断点在 Matlab 编辑器窗口中不可见?

NestJs/swagger:定义没有 DTO 类的引用模式

为啥提交在 github 上可见但在本地代表中不可见?

为啥同步融合 DomainUpDown 控件在 wpf 中不可见?

为啥 $ids 在 whereHas() 的回调中不可见?