NestJs/swagger: 定义没有 DTO 的引用模式 类
NestJs/swagger: Define ref schemas without DTO classes
我有一个应用程序,我根据 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 class 并为每个 class [=38= 使用 ApiProperty
装饰器].就我而言,这意味着我必须将 open-api 规范中的所有普通对象模式重构为 DTO classes.
有没有办法将原始模式提供给库并获得预期的结果?
// instead of this:
class CatDto {
@ApiProperty()
name: string;
}
// I want to do:
const catSchema = {
type: 'object',
properties: {
name: { type: 'string' }
}
}
经过日复一日的反复试验,我在 Javascript.
中使用了一个有趣的技巧来解决这个问题
首先,我将 open-api 规范创建为普通对象(如问题中所问)。然后将它传递给一个新的装饰器,魔法就在这里发生了。
在装饰器中,我创建了一个具有预定义名称的 DTO class,并将属性从普通对象映射到 DTO class。棘手的部分是动态地给它起一个名字。这可以通过以下技术实现。
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/swagger
的 ApiResponse
装饰器以达到预期的结果。
不知道是不是你想要的,我是这样做的
@ApiResponse({
status: 200,
schema: {
example: // write the response you want here
[
{
userId: 1,
name: 'name',
},
],
},
})
我想这也可以通过使用 getSchemaPath
和 ApiExtraModels
:
来实现
import { ApiExtraModels, ApiResponse, getSchemaPath } from '@nestjs/swagger';
@ApiExtraModels(CatDto) // for CatDto to be found by getSchemaPath()
@ApiResponse({
schema: {
'$ref': getSchemaPath(CatDto)
}
})
关于额外型号的更多信息:https://docs.nestjs.com/openapi/types-and-parameters#extra-models
In my case, that means I have to refactor all the plain object schemas in open-api spec to be DTO classes.
不需要手动标注对象,也可以使用这个插件,就是opt-in:https://docs.nestjs.com/openapi/cli-plugin
我有一个应用程序,我根据 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 class 并为每个 class [=38= 使用 ApiProperty
装饰器].就我而言,这意味着我必须将 open-api 规范中的所有普通对象模式重构为 DTO classes.
有没有办法将原始模式提供给库并获得预期的结果?
// instead of this:
class CatDto {
@ApiProperty()
name: string;
}
// I want to do:
const catSchema = {
type: 'object',
properties: {
name: { type: 'string' }
}
}
经过日复一日的反复试验,我在 Javascript.
中使用了一个有趣的技巧来解决这个问题首先,我将 open-api 规范创建为普通对象(如问题中所问)。然后将它传递给一个新的装饰器,魔法就在这里发生了。
在装饰器中,我创建了一个具有预定义名称的 DTO class,并将属性从普通对象映射到 DTO class。棘手的部分是动态地给它起一个名字。这可以通过以下技术实现。
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/swagger
的 ApiResponse
装饰器以达到预期的结果。
不知道是不是你想要的,我是这样做的
@ApiResponse({
status: 200,
schema: {
example: // write the response you want here
[
{
userId: 1,
name: 'name',
},
],
},
})
我想这也可以通过使用 getSchemaPath
和 ApiExtraModels
:
import { ApiExtraModels, ApiResponse, getSchemaPath } from '@nestjs/swagger';
@ApiExtraModels(CatDto) // for CatDto to be found by getSchemaPath()
@ApiResponse({
schema: {
'$ref': getSchemaPath(CatDto)
}
})
关于额外型号的更多信息:https://docs.nestjs.com/openapi/types-and-parameters#extra-models
In my case, that means I have to refactor all the plain object schemas in open-api spec to be DTO classes.
不需要手动标注对象,也可以使用这个插件,就是opt-in:https://docs.nestjs.com/openapi/cli-plugin