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

Pet*_*ter 7 javascript nestjs nestjs-swagger

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

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

dto:

export class HealthCheckDataDto {
    serverStatus: {} // dont have it typed yet;
    dbStatus: MongoConnectionStateT;
} 
Run Code Online (Sandbox Code Playgroud)

昂首阔步:

[
  {
    "serverStatus": {},
    "dbStatus": {}
  }
]
Run Code Online (Sandbox Code Playgroud)

swagger 示例值中的预期结果:

[
  {
    "serverStatus": {},
    "dbStatus": {
      "isOnline": true,
      "msg": "string"
    }
  }
]
Run Code Online (Sandbox Code Playgroud)

这是函数:

@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);
}
Run Code Online (Sandbox Code Playgroud)

我试过的:

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

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

drk*_*gel 11

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

添加:

  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
Run Code Online (Sandbox Code Playgroud)

nest-cli.json,并添加:

import { ApiProperty, ApiBody } from '@nestjs/swagger';
Run Code Online (Sandbox Code Playgroud)

到您的每个 DTO,该插件将自动注释并记录您的模式!


小智 8

根据 类型和参数的文档 ,您只需使用

@Body(), @Query(), @Param()
Run Code Online (Sandbox Code Playgroud)

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

{
"collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger/plugin"]
  }
}
Run Code Online (Sandbox Code Playgroud)

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

请注意,如果这不会自动显示它们或将架构显示为空,那么您可以装饰 dto 的至少一个条目,然后@ApiProperty()刷新页面。这会让事情完成。


Pet*_*ter 7

我错过了NestJS 文档中的一处:泛型和接口

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

嗯,这是有道理的。

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

因此,对我有用的最终设置如下

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

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