nestjs - NestJs/swagger:定义没有 DTO 类的引用模式
问题描述
我有一个应用程序,我根据 open-api 规范将 API 响应模式定义为纯 javascript 对象。目前我将其传递给ApiResponse
@nestjs/swagger 中的装饰器,如下所示:
class CatsController {
@Get()
@ApiResponse({
status: 200,
schema: catSchema // plain js object imported from another file
})
getAll() {}
}
这很好用。但是,输出的 open-api 规范包含每个使用catSchema
. 相反,我希望输出 swagger 文件在该部分下具有 catSchema ,并在路径部分中components
有一个对应的部分。$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' }
}
}
解决方案
经过几天和几天的试验和错误,我能够使用 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 可以传递给ApiResponse
装饰器@nestjs/swagger
以达到预期的结果。
推荐阅读
- php - 解析错误:第 7 行 C:\xampp\htdocs\script\includes\application_top.php 中的语法错误、意外的 ','、期望 ')'
- javascript - 如何在 Angular 2 项目中使用脚本标签
- javascript - 无法使用 react-redux 更新状态
- bash - bash循环覆盖下一个文件
- jsf - 用于 p:selectOneMenu 转换器的应用范围 bean
- java - 在应用中间安装apk - Android Studio
- android - 如何显示所有聊天 Mesibo Android SDK
- git - git checkout 文件夹到底是做什么的?
- asp.net - 在 Redis 中存储临时块上传的文件
- python - python中张量切片中的值总和