SwaggerModule
在路由处理程序中搜索所有 @Body()
、@Query()
和 @Param()
装饰器以生成 API 文档。它还利用反射创建相应的模型定义。请考虑以下代码:
@Post()
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
要显式设置主体定义,请使用 @ApiBody()
装饰器(从 @nestjs/swagger
包导入)。
基于 CreateCatDto
,将创建以下模型定义 Swagger UI:
如您所见,尽管该类具有一些声明的属性,但该定义为空。为了使类属性对 SwaggerModule
可见,我们必须使用 @ApiProperty()
装饰器对其进行注释,或者使用 CLI 插件(在 插件 部分中阅读更多内容),它将自动执行此操作:
import { ApiProperty } from '@nestjs/swagger'
export class CreateCatDto {
@ApiProperty()
name: string
@ApiProperty()
age: number
@ApiProperty()
breed: string
}
无需手动注释每个属性,请考虑使用 Swagger 插件(请参阅 插件 部分),它将自动为您提供此功能。
让我们打开浏览器并验证生成的 CreateCatDto
模型:
此外,@ApiProperty()
装饰器允许设置各种 Schema Object 属性:
@ApiProperty({
description: 'The age of a cat',
minimum: 1,
default: 1,
})
age: number;
您可以使用 @ApiPropertyOptional()
简写装饰器,而不必明确键入 {{"@ApiProperty({ required: false })"}}
。
为了明确设置属性的类型,请使用 type
键:
@ApiProperty({
type: Number,
})
age: number;
Arrays
当属性是数组时,我们必须手动指示数组类型,如下所示:
@ApiProperty({ type: [String] })
names: string[];
考虑使用 Swagger 插件(请参阅 插件 部分),它将自动检测数组。
将类型作为数组的第一个元素(如上所示)或将isArray
属性设置为true
。
循环依赖
当类之间存在循环依赖时,使用惰性函数为SwaggerModule
提供类型信息:
@ApiProperty({ type: () => Node })
node: Node;
考虑使用 Swagger 插件(参见 插件 部分),它将自动检测循环依赖关系。
泛型和接口
由于 TypeScript 不存储有关泛型或接口的元数据,因此当您在 DTO 中使用它们时,SwaggerModule
可能无法在运行时正确生成模型定义。例如,Swagger 模块无法正确检查以下代码:
createBulk(@Body() usersDto: CreateUserDto[])
为了克服这一限制,您可以明确设置类型:
@ApiBody({ type: [CreateUserDto] })
createBulk(@Body() usersDto: CreateUserDto[])
Enums
要识别枚举
,我们必须使用值数组手动设置@ApiProperty
上的枚举
属性。
@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
或者,定义一个实际的 TypeScript 枚举,如下所示:
export enum UserRole {
Admin = 'Admin',
Moderator = 'Moderator',
User = 'User',
}
然后,您可以将枚举直接与@Query()
参数装饰器结合使用,并与@ApiQuery()
装饰器结合使用。
@ApiQuery({ name: 'role', enum: UserRole })
async filterByRole(@Query('role') role: UserRole = UserRole.User) {}
将isArray
设置为true后,可以将枚举
选择为多选:
Enums schema
默认情况下,枚举
属性将在参数
上添加 Enum 的原始定义。
- breed:
type: string
enum:
- Persian
- Tabby
- Siamese
上述规范在大多数情况下都适用。但是,如果您使用的工具将规范作为输入并生成客户端代码,则可能会遇到生成的代码包含重复的枚举
的问题。请考虑以下代码片段:
// generated client-side code
export class CatDetail {
breed: CatDetailEnum
}
export class CatInformation {
breed: CatInformationEnum
}
export enum CatDetailEnum {
Persian = 'Persian',
Tabby = 'Tabby',
Siamese = 'Siamese',
}
export enum CatInformationEnum {
Persian = 'Persian',
Tabby = 'Tabby',
Siamese = 'Siamese',
}
上面的代码片段是使用名为 NSwag 的工具生成的。
您可以看到现在有两个完全相同的 enums
。
为了解决这个问题,您可以在装饰器中传递 enumName
和 enum
属性。
export class CatDetail {
@ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
breed: CatBreed
}
enumName
属性使 @nestjs/swagger
能够将 CatBreed
转换为其自己的 schema
,从而使 CatBreed
枚举可重复使用。规范如下所示:
CatDetail:
type: 'object'
properties:
...
- breed:
schema:
$ref: '#/components/schemas/CatBreed'
CatBreed:
type: string
enum:
- Persian
- Tabby
- Siamese
任何以 enum
作为属性的 装饰器 也将采用 enumName
。
Raw definitions
在某些特定场景中(例如,深度嵌套数组、矩阵),您可能需要手动描述您的类型。
@ApiProperty({
type: 'array',
items: {
type: 'array',
items: {
type: 'number',
},
},
})
coords: number[][];
同样,为了在控制器类中手动定义输入/输出内容,请使用 schema
属性:
@ApiBody({
schema: {
type: 'array',
items: {
type: 'array',
items: {
type: 'number',
},
},
},
})
async create(@Body() coords: number[][]) {}
Extra models
要定义控制器中未直接引用但应由 Swagger 模块检查的其他模型,请使用 @ApiExtraModels()
装饰器:
@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
您只需对特定模型类使用一次 @ApiExtraModels()
。
或者,您可以将指定了 extraModels
属性的选项对象传递给 SwaggerModule#createDocument()
方法,如下所示:
const document = SwaggerModule.createDocument(app, options, {
extraModels: [ExtraModel],
})
要获取模型的引用($ref
),请使用 getSchemaPath(ExtraModel)
函数:
'application/vnd.api+json': {
schema: { $ref: getSchemaPath(ExtraModel) },
},
oneOf, anyOf, allOf
要组合模式,您可以使用 oneOf
、anyOf
或 allOf
关键字(阅读更多)。
@ApiProperty({
oneOf: [
{ $ref: getSchemaPath(Cat) },
{ $ref: getSchemaPath(Dog) },
],
})
pet: Cat | Dog;
如果要定义多态数组(即,其成员跨越多个模式的数组),则应使用原始定义(参见上文)手动定义类型。
type Pet = Cat | Dog;
@ApiProperty({
type: 'array',
items: {
oneOf: [
{ $ref: getSchemaPath(Cat) },
{ $ref: getSchemaPath(Dog) },
],
},
})
pets: Pet[];
getSchemaPath()
函数从 @nestjs/swagger
导入。
必须使用 @ApiExtraModels()
装饰器(在类级别)将 Cat
和 Dog
定义为额外模型。