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

Posted

技术标签:

【中文标题】NestJs/swagger:定义没有 DTO 类的引用模式【英文标题】:NestJs/swagger: Define ref schemas without DTO classes 【发布时间】:2021-01-06 17:51:07 【问题描述】:

我有一个应用程序,我根据 open-api 规范将 API 响应模式定义为纯 javascript 对象。目前我将其传递给@nestjs/swagger 中的ApiResponse 装饰器,如下所示:

class CatsController 

  @Get()
  @ApiResponse(
    status: 200,
    schema: catSchema // plain js object imported from another file
  )
  getAll() 

这很好用。但是,输出的 open-api 规范包含每个使用 catSchema 的端点的详细架构。 相反,我希望输出 swagger 文件在 components 部分下具有 catSchema,并在路径部分中具有相应的 $ref

components:
  schemas:
    Cat:
      properties:
        name:
          type: string
paths:
  /cats/id:
    get:
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Cat'

到目前为止,似乎唯一的方法是将架构定义为 DTO 类并为每个类属性使用 ApiProperty 装饰器。就我而言,这意味着我必须将 open-api 规范中的所有普通对象模式重构为 DTO 类。

有没有办法将原始模式提供给库并获得预期的结果?

// instead of this:
class CatDto 
  @ApiProperty()
  name: string;


// I want to do:
const catSchema = 
  type: 'object',
  properties: 
    name:  type: 'string' 
  

【问题讨论】:

简而言之,不,这背后的原因是:@ApiProperty 是 NestJs 中 swagger 理解架构的标签,在内联架构设计中不支持。你能更详细地解释一下你想如何传递模式吗? 感谢@TanmoyBhattacharjee 的回复。我想将内联模式直接传递给@ApiResponse。它工作得很好,除了它不做$ref 模式。输出包含直接在响应部分下的架构。这有意义吗? 【参考方案1】:

经过几天和几天的反复试验,我能够使用 Javascript 中的一个有趣技巧来完成这项工作。

首先,我将 open-api 规范创建为普通对象(如问题中所述)。然后将它传递给一个新的装饰器,魔法就会发生。

在装饰器中,我创建了一个具有预定义名称的 DTO 类,并将属性从普通对象映射到 DTO 类。棘手的部分是动态地给它命名。这可以通过以下技术实现。

const dynamicName = 'foo'; // passed as a parameter to the decorator

class IntermediateDTO 
  @ApiProperty(schema) // schema as a plain object
  data: any;


const proxyObject = 
  [dynamicName] = class extends IntermediateDTO 

通过使用代理对象,并将class extends IntermediateDTO 分配给其中的一个属性,条目会动态地获得一个名称。现在可以将这个带有动​​态名称的新 DTO 传递给 @nestjs/swaggerApiResponse 装饰器以达到预期的效果。

【讨论】:

以上是关于NestJs/swagger:定义没有 DTO 类的引用模式的主要内容,如果未能解决你的问题,请参考以下文章

@nestjs/swagger:如何在没有 @ApiOkResponse 装饰器的情况下添加架构?

Nestjs IsEnum dto 验证和招摇

NestJs Swagger:如何为动态类定义 Api 属性

NestJs Swagger 混合类型

@nestjs/swagger 没有设置授权标头

NestJS/swagger:ApiExtraModel 期望啥模型作为参数?