OPENAPI
介绍
OpenAPI是一个与语言无关的RESTful API定义说明,Nest提供了一个专有的模块来利用装饰器生成类似声明。
安装
要开始使用,首先安装依赖、
$ npm install --save @nestjs/swagger swagger-ui-express
如果使用fastify,安装fastify-swagger而不是swagger-ui-express:
$ npm install --save @nestjs/swagger fastify-swagger
引导
安装完成后,在main.ts文件中定义并初始化SwaggerModule类:
import { NestFactory } from '@nestjs/core';import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';import { AppModule } from './app.module';async function bootstrap() {const app = await NestFactory.create(AppModule);const config = new DocumentBuilder().setTitle('Cats example').setDescription('The cats API description').setVersion('1.0').addTag('cats').build();const document = SwaggerModule.createDocument(app, config);SwaggerModule.setup('api', app, document);await app.listen(3000);}bootstrap();
?> 文档(通过SwaggerModule#createDocument()方法返回)是一个遵循OpenAPI文档的序列化对象。除了HTTP,你也可以以JSON/YAML文件格式保存和使用它。
DocumentBuilder建立一个遵循OpenAPI 标准的基础文档。它提供了不同的方法来配置类似标题、描述、版本等信息属性。要创建一个完整的文档(使用HTTP定义),我们使用SwaggerModule类的createDocument()方法。这个方法有两个参数,一个应用实例和一个Swagger选项对象。我们也可以提供第三个SwaggerDocumentOptions类型可选对象,见文档选项。
创建文档后,调用setup()方法,它接受:
- 挂载Swagger界面的路径。
- 应用实例。
- 上述实例化的文档对象。
运行以下命令启动HTTP服务器。
$ npm run start
浏览http://localhost:3000/api可以看到Swagger界面。

Swagger模块自动反射你所有的终端。注意Swagger界面根据平台不同,由swagger-ui-express或fastify-swagger生成。
?> 要生成和下载一个Swagger JSON文件,导航到http://localhost:3000/api-json (swagger-ui-express) 或http://localhost:3000/api/json (fastify-swagger) (假设API文档在 http://localhost:3000/api路径)。
!> 在使用fastify-swagger和helmet时可能有CSP问题,要处理这个冲突,参考如下配置CSP。
app.register(helmet, {contentSecurityPolicy: {directives: {defaultSrc: [`'self'`],styleSrc: [`'self'`, `'unsafe-inline'`],imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],scriptSrc: [`'self'`, `https: 'unsafe-inline'`],},},});
// If you are not going to use CSP at all, you can use this: app.register(helmet, { contentSecurityPolicy: false, });
文档选项
创建文档时,可以提供一些额外选项来配合库特性。这些选项应该是SwaggerDocumentOptions类型:
export interface SwaggerDocumentOptions {/*** List of modules to include in the specification*/include?: Function[];/*** Additional, extra models that should be inspected and included in the specification*/extraModels?: Function[];/*** If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method*/ignoreGlobalPrefix?: boolean;/*** If `true`, swagger will also load routes from the modules imported by `include` modules*/deepScanRoutes?: boolean;/*** Custom operationIdFactory that will be used to generate the `operationId`* based on the `controllerKey` and `methodKey`* @default () => controllerKey_methodKey*/operationIdFactory?: (controllerKey: string, methodKey: string) => string;}
例如,如果你要确保库像createUser而不是UserController_createUser一样生成操作名称,可以做如下配置:
const options: SwaggerDocumentOptions = {operationIdFactory: (controllerKey: string,methodKey: string) => methodKey});const document = SwaggerModule.createDocument(app, config, options);
示例
一个例子见这里。
类型和参数
SwaggerModule在路径处理程序上搜索所有@Body(), @Query(), 以及@Param()装饰器来生成API文档。它也利用反射来创建响应模型。考虑以下代码:
@Post()async create(@Body() createCatDto: CreateCatDto) {this.catsService.create(createCatDto);}
?> 要显式定义主体,使用@ApiBody()装饰器 (从@nestjs/swagger引入).
基于CreateCatDto,将创建以下Swagger页面模型。

如你所见,虽然类已经声明了一些属性,但这里的定义是空的。要使这些类属性在SwaggerModule中可见,我们要么用@ApiProperty()装饰器或使用CLI插件来自动生成:
import { ApiProperty } from '@nestjs/swagger';export class CreateCatDto {@ApiProperty()name: string;@ApiProperty()age: number;@ApiProperty()breed: string;}
?> 考虑使用Swagger插件(参见CLI插件)来自动生成以代替手动装饰每个属性。
打开浏览器确认生成的CreateCatDto模型:

@ApiProperty()装饰器也允许设置不同的原型对象属性:
@ApiProperty({description: 'The age of a cat',minimum: 1,default: 1,})age: number;
?> 可以使用@ApiPropertyOptional()速记装饰器来替代显式输入@ApiProperty({ required: false })。
要显式指定属性类型,使用type字段:
@ApiProperty({type: Number,})age: number;
数组
当属性是数组时,我们必须手动指定数组类型:
@ApiProperty({ type: [String] })names: string[];
考虑使用Swagger 插件来自动发现数组
要么将类型作为数组的第一个元素(如上),要么将isArray属性设为true。
循环依赖
当你的类之间有循环依赖时,使用SwaggerModul提供的一个包含类型信息的懒函数。
@ApiProperty({ type: () => Node })node: Node;
考虑使用Swagger 插件来自动发现循环依赖
泛型和接口
由于TypeScript没有存储泛型或者接口的元数据,当你在DTO中使用他们的时候,SwaggerModule可能不会正确生成运行时的模型定义。基于此,下列代码不会被Swagger模块正确识别。
createBulk(@Body() usersDto: CreateUserDto[])
要处理这些限制,需要显式配置类型:
@ApiBody({ type: [CreateUserDto] })createBulk(@Body() usersDto: CreateUserDto[])
枚举
要定义一个枚举,需要在@ApiProperty中用数组手动设置enum属性。
@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})role: UserRole;
也可以如下定义一个真实的TypeScript泛型:
export enum UserRole {Admin = 'Admin',Moderator = 'Moderator',User = 'User',}
可以在@Query()参数中配合@ApiQuery()装饰器直接使用enum:
@ApiQuery({ name: 'role', enum: UserRole })async filterByRole(@Query('role') role: UserRole = UserRole.User) {}

当isArray配置为true时, enum可以多选。

枚举原型
默认地,enum属性将为Enum在parameter上添加一个原始定义。
- breed:type: 'string'enum:- Persian- Tabby- Siamese
上述定义在大部分情况下工作良好。然而,如果你使用该定义作为输入在客户端生成代码时,可能会遇到属性包含重复枚举的情况,考虑以下代码:
// generated client-side codeexport 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工具生成
现在可以看到有两个枚举完全一样,要处理这个问题,需要在装饰器的enum属性中传入enumName参数。
export class CatDetail {@ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })breed: CatBreed;}
enumName属性使能@nestjs/swagger来将CatBreed转换为其原型,从而使CatBreed可重用:
CatDetail:type: 'object'properties:...- breed:schema:$ref: '#/components/schemas/CatBreed'CatBreed:type: stringenum:- Persian- Tabby- Siamese
?> 任何包含enum属性的装饰器都有enumName
原始定义
在一些特殊场合(例如深度嵌套的数组和矩阵),你可能需要手动描述你的类型。
@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[][]) {}
额外模型
要定义控制器中没有直接使用,但是需要被Swagger模块检查的额外的模型,使用@ApiExtraModels()装饰器:
@ApiExtraModels(ExtraModel)export class CreateCatDto {}
?> 只需要对指定的model类使用一次@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引入.
Cat和Dog都应该使用@ApiExtraModels()装饰器 (在类水平).
操作
在OpenAPI规范中,API暴露的以{资源}为结束的终端,例如/users或者/reports/summary,都是可以执行HTTP方法的,例如GET,POST或者DELETE。
标签
要为控制器附加一个标签,使用`@ApiTags(…tags)装饰器。
@ApiTags('cats')@Controller('cats')export class CatsController {}
报头
要作为请求的一部分定义自定义报头,使用@ApiHeader()装饰器。
@ApiHeader({name: 'X-MyHeader',description: 'Custom header',})@Controller('cats')export class CatsController {}
响应
要定义一个自定义响应, 使用`@ApiResponse()装饰器.
@Post()@ApiResponse({ status: 201, description: 'The record has been successfully created.'})@ApiResponse({ status: 403, description: 'Forbidden.'})async create(@Body() createCatDto: CreateCatDto) {this.catsService.create(createCatDto);}
Nest提供了一系列继承自@ApiResponse装饰器的用于速记的API响应装饰器:
- @ApiOkResponse()
- @ApiCreatedResponse()
- @ApiAcceptedResponse()
- @ApiNoContentResponse()
- @ApiMovedPermanentlyResponse()
- @ApiBadRequestResponse()
- @ApiUnauthorizedResponse()
- @ApiNotFoundResponse()
- @ApiForbiddenResponse()
- @ApiMethodNotAllowedResponse()
- @ApiNotAcceptableResponse()
- @ApiRequestTimeoutResponse()
- @ApiConflictResponse()
- @ApiTooManyRequestsResponse()
- @ApiGoneResponse()
- @ApiPayloadTooLargeResponse()
- @ApiUnsupportedMediaTypeResponse()
- @ApiUnprocessableEntityResponse()
- @ApiInternalServerErrorResponse()
- @ApiNotImplementedResponse()
- @ApiBadGatewayResponse()
- @ApiServiceUnavailableResponse()
- @ApiGatewayTimeoutResponse()
- @ApiDefaultResponse()
@Post()@ApiCreatedResponse({ description: 'The record has been successfully created.'})@ApiForbiddenResponse({ description: 'Forbidden.'})async create(@Body() createCatDto: CreateCatDto) {this.catsService.create(createCatDto);}
要从请求返回一个指定的模型,需要创建一个类并用@ApiProperty()装饰器注释它。
export class Cat {@ApiProperty()id: number;@ApiProperty()name: string;@ApiProperty()age: number;@ApiProperty()breed: string;}
Cat模型可以与响应装饰器的type属性组合使用。
@ApiTags('cats')@Controller('cats')export class CatsController {@Post()@ApiCreatedResponse({description: 'The record has been successfully created.',type: Cat,})async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {return this.catsService.create(createCatDto);}}
打开浏览器确认生成的Cat模型。

文件上传
使用@ApiBody装饰器和@ApiConsumes()来使能文件上传,这里有一个完整的使用文件上传技术的例子。
@UseInterceptors(FileInterceptor('file'))@ApiConsumes('multipart/form-data')@ApiBody({description: 'List of cats',type: FileUploadDto,})uploadFile(@UploadedFile() file) {}
FileUploadDto像这样定义:
class FileUploadDto {@ApiProperty({ type: 'string', format: 'binary' })file: any;}
要处理多个文件上传,如下定义FilesUploadDto:
class FilesUploadDto {@ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })files: any[];}
扩展
要为请求增加一个扩展使用@ApiExtension()装饰器. 该扩展名称必须以 x-前缀。
@ApiExtension('x-foo', { hello: 'world' })
高级主题:通用ApiResponse
基于原始定义,的能力,我们可以为Swagger定义通用原型:
export class PaginatedDto<TData> {@ApiProperty()total: number;@ApiProperty()limit: number;@ApiProperty()offset: number;results: TData[];}
我们跳过了定义results,因为后面要提供一个原始定义。现在,我们定义另一个DTO,例如CatDto如下:
export class CatDto {@ApiProperty()name: string;@ApiProperty()age: number;@ApiProperty()breed: string;}
我们可以定义一个PaginatedDto<CatDto>响应如下:
@ApiOkResponse({schema: {allOf: [{ $ref: getSchemaPath(PaginatedDto) },{properties: {results: {type: 'array',items: { $ref: getSchemaPath(CatDto) },},},},],},})async findAll(): Promise<PaginatedDto<CatDto>> {}
在这个例子中,我们指定响应拥有所有的PaginatedDto并且results属性类型为CatDto数组。
getSchemaPath()函数从一个给定模型的OpenAPI指定文件返回OpenAPI原型路径allOf是一个OAS3的概念,包括各种各样相关用例的继承。
最后,因为PaginatedDto没有被任何控制器直接引用,SwaggerModule还不能生成一个相应的模型定义。我们需要一个额外的模型,可以在控制器水平使用@ApiExtraModels()装饰器。
@Controller('cats')@ApiExtraModels(PaginatedDto)export class CatsController {}
如果你现在运行Swagger,为任何终端生成的swagger.json文件看上去应该像定义的这样:
"responses": {"200": {"description": "","content": {"application/json": {"schema": {"allOf": [{"$ref": "#/components/schemas/PaginatedDto"},{"properties": {"results": {"$ref": "#/components/schemas/CatDto"}}}]}}}}}
为了让其可重用,我们为PaginatedDto像这样创建一个装饰器:
export const ApiPaginatedResponse = <TModel extends Type<any>>(model: TModel,) => {return applyDecorators(ApiOkResponse({schema: {allOf: [{ $ref: getSchemaPath(PaginatedDto) },{properties: {results: {type: 'array',items: { $ref: getSchemaPath(model) },},},},],},}),);};
?> Type<any>接口和applyDecorators函数从@nestjs/common引入.
我们现在可以为终端使用自定义的@ApiPaginatedResponse()装饰器 :
@ApiPaginatedResponse(CatDto)async findAll(): Promise<PaginatedDto<CatDto>> {}
作为客户端生成工具,这一方法为客户端提供了一个含糊的PaginatedResponse<TModel>。下面示例展示了生成的客户端访问GET /终端的结果。
// AngularfindAll(): Observable<{ total: number, limit: number, offset: number, results: CatDto[] }>
可以看出,这里的返回类型是含糊不清的。要处理这个问题,可以为ApiPaginatedResponse的原型添加title属性。
export const ApiPaginatedResponse = <TModel extends Type<any>>(model: TModel) => {return applyDecorators(ApiOkResponse({schema: {title: `PaginatedResponseOf${model.name}`allOf: [// ...],},}),);};
现在结果变成了。
// AngularfindAll(): Observable<PaginatedResponseOfCatDto>
安全
要确定某个特定操作使用哪个安全机制,使用@ApiSecurity()装饰器。
@ApiSecurity('basic')@Controller('cats')export class CatsController {}
在运行程序前,使用DocumentBuilder在基础文档里添加安全定义。
const options = new DocumentBuilder().addSecurity('basic', {type: 'http',scheme: 'basic',});
一些最常用的认证机制是内置的(例如basic和bearer),因此不需要像上面那样手动定义。
Basic认证
使用@ApiBasicAuth()配置basic认证。
@ApiBasicAuth()@Controller('cats')export class CatsController {}
在运行程序前,使用DocumentBuilder在基础文档里添加安全定义。
const options = new DocumentBuilder().addBasicAuth();
Bearer认证
使用@ApiBearerAuth()启用bearer认证。
@ApiBearerAuth()@Controller('cats')export class CatsController {}
在运行程序前,使用DocumentBuilder在基础文档里添加安全定义。
const options = new DocumentBuilder().addBearerAuth();
OAuth2认证
使用@ApiOAuth2()启用OAuth2认证。
@ApiOAuth2(['pets:write'])@Controller('cats')export class CatsController {}
在运行程序前,使用DocumentBuilder在基础文档里添加安全定义。
const options = new DocumentBuilder().addOAuth2();
Cookie认证
使用@ApiCookieAuth()启用cookie认证。
@ApiCookieAuth()@Controller('cats')export class CatsController {}
在运行程序前,使用DocumentBuilder在基础文档里添加安全定义。
const options = new DocumentBuilder().addCookieAuth('optional-session-id');
映射的类型
像构建CRUD特性一样,通常需要基于实体类型创建变体。Nest提供了一些应用函数来进行类型变换,以让这类变换工作更简单。
Partial(部分声明)
在创建数据转换对象(也称为DTO),将创建和更新创建为同一类型通常很有用。例如,创建变体可能需要所有字段,但更新变体可能将所有字段都配置为可选的。
Nest提供了PartialType()应用函数让这一任务更简单地最小化构造。
PartialType()函数返回一个类型(类)将输入的所有属性配置为可选的。例如,你可以这样创建一个类型。
import { ApiProperty } from '@nestjs/swagger';export class CreateCatDto {@ApiProperty()name: string;@ApiProperty()age: number;@ApiProperty()breed: string;}
默认所有的字段都是必须的。要创建一个所有字段与之相同但都是可选的字段,使用PartialType()并将CreateCatDto作为参数。
export class UpdateCatDto extends PartialType(CreateCatDto) {}
?> PartialType()函数从@nestjs/swagger引入.
Pick(拾取)
PickType()函数从输入类型中拾取一部分属性并生成一个新类型(类) 。假设我们起始类如下:
import { ApiProperty } from '@nestjs/swagger';export class CreateCatDto {@ApiProperty()name: string;@ApiProperty()age: number;@ApiProperty()breed: string;}
我们使用PickType()从中拾取一部分属性:
export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
?> PickType()函数 从@nestjs/swagger引入.
Omit(省略)
OmitType()函数拾取所有输入属性,移除指定部分属性。例如,我们起始类型如下:
import { ApiProperty } from '@nestjs/swagger';export class CreateCatDto {@ApiProperty()name: string;@ApiProperty()age: number;@ApiProperty()breed: string;}
我们可以以此创建一个除name之外的包含其他所有属性的类。OmitType函数的第二个参数是包含要移除属性名称的数组。
export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
?> OmitType()函数从@nestjs/swagger引入.
Intersection(交叉)
IntersectionType()函数将两个类型组合为一个类型(类),例如,我们起始的两个类型如下:
import { ApiProperty } from '@nestjs/swagger';export class CreateCatDto {@ApiProperty()name: string;@ApiProperty()breed: string;}export class AdditionalCatInfo {@ApiProperty()color: string;}
我们可以生成一个由两个类中所有属性组成的新类型。
export class UpdateCatDto extends IntersectionType(CreateCatDto,AdditionalCatInfo,) {}
?>IntersectionType()函数从@nestjs/swagger引入.
Composition(组合)
映射类型的使用时可以组合的,例如,以下代码创建一个类型(类),它包含了CreateCatDto除了name之外的所有属性,并将所有属性设置为可选的。
export class UpdateCatDto extends PartialType(OmitType(CreateCatDto, ['name'] as const),) {}
装饰器
所有可用的OpenAPI装饰器都有Api前缀用以和核心装饰器区分。下面是完整的装饰器名称列表以及其可能能应用的范围。
| 名称 | 类型 |
|---|---|
@ApiOperation()|Method @ApiResponse()|Method / Controller @ApiProduces()|Method / Controller @ApiConsumes()|Method / Controller @ApiBearerAuth()|Method / Controller @ApiOAuth2()|Method / Controller @ApiBasicAuth()|Method / Controller @ApiSecurity()|Method / Controller @ApiExtraModels()|Method / Controller @ApiBody()|Method @ApiParam()|Method @ApiQuery()|Method @ApiHeader()|Method / Controller @ApiExcludeEndpoint()|Method @ApiTags()|Method / Controller @ApiProperty()|Model @ApiPropertyOptional()|Model @ApiHideProperty()|Model @ApiExtension()|Method
CLI插件
TypeScript的元数据反射系统有一些限制,一些功能因此不可能实现,例如确定一个类由哪些属性组成,或者一个属性是可选的还是必须的。然而,一些限制可以在编译时强调。Nest提供了一个增强TypeScript编译过程的插件来减少需要的原型代码量。
?> 这个插件是一个opt-in,你也可以选择手动声明所有的装饰器,或者仅仅声明你需要的。
概述
Swagger插件可以自动:
- 使用
@ApiProperty注释所有除了用@ApiHideProperty装饰的DTO属性。 - 根据问号符号确定
required属性(例如name?: string将设置required: false) - 根据类型配置
type为enum(也支持数组) - 基于给定的默认值配置默认参数
- 基于
class-validator装饰器配置一些验证策略(如果classValidatorShim配置为true) - 为每个终端添加一个响应装饰器,包括合适的状态和类型(响应模式)
- 根据注释生成属性和终端的描述(如果
introspectComments配置为true) - 基于注释生成属性的示例数据(如果
introspectComments配置为true)
注意,你的文件名必须有如下后缀: ['.dto.ts', '.entity.ts'] (例如create-user.dto.ts) 才能被插件分析。
如果使用其他后缀,你可以调整插件属性来指定dtoFileNameSuffix选项(见下文)。
之前,如果你想要通过Swagger提供一个交互体验,你必须复制大量代码让包知道你的模型/组件在该声明中。例如,你可以定义一个CreateUserDto类:
export class CreateUserDto {@ApiProperty()email: string;@ApiProperty()password: string;@ApiProperty({ enum: RoleEnum, default: [], isArray: true })roles: RoleEnum[] = [];@ApiProperty({ required: false, default: true })isEnabled?: boolean = true;}
在中等项目中这还不是问题,但是一旦有大量类的话这就变得冗余而难以维护。
要应用Swagger插件,可以简单声明上述类定义:
export class CreateUserDto {email: string;password: string;roles: RoleEnum[] = [];isEnabled?: boolean = true;}
插件可以通过抽象语法树添加合适的装饰器,你不在需要在代码中到处写ApiProperty装饰器。
?> 插件可以自动生成所有缺失的swagger属性,但是如果你要覆盖他们,只需要通过@ApiProperty()显式声明即可。
注释自省
注释自省特性使能后,CLI插件可以基于注释生成描述和示例值。
例如,一个给定的roles属性示例:
/*** A list of user's roles* @example ['admin']*/@ApiProperty({description: `A list of user's roles`,example: ['admin'],})roles: RoleEnum[] = [];
你必须复制描述和示例值。当introspectComments使能后,CLI插件可以自动解压这些注释并提供描述(以及示例,如果定义了的话)。现在,上述属性可以简化为:
/*** A list of user's roles* @example ['admin']*/roles: RoleEnum[] = [];
使用CLI插件
要使能CLI插件,打开nest-cli.json (如果你在用Nest CLI)并添加以下插件配置:
{"collection": "@nestjs/schematics","sourceRoot": "src","compilerOptions": {"plugins": ["@nestjs/swagger"]}}
你可以使用其他options属性来自定义插件特性。
"plugins": [{"name": "@nestjs/swagger","options": {"classValidatorShim": false,"introspectComments": true}}]
options属性实现以下接口:
export interface PluginOptions {dtoFileNameSuffix?: string[];controllerFileNameSuffix?: string[];classValidatorShim?: boolean;introspectComments?: boolean;}
| 选项 | 默认 | 说明 |
|---|---|---|
| dtoFileNameSuffix | [‘.dto.ts’, ‘.entity.ts’] | DTO (数据传输对象)文件后缀 |
| controllerFileNameSuffix | .controller.ts | 控制文件后缀 |
| classValidatorShim | true | 如果配置为true,模块将重用class-validator验证装饰器 (例如@Max(10)将在schema定义中增加max: 10) |
| introspectComments | false | 如果配置为true,插件将根据描述注释生成说明和示例 |
如果不使用CLI,但是使用一个用户定义的Webpack配置,可以和ts-loader配合使用该插件:
getCustomTransformers: (program: any) => ({before: [require('@nestjs/swagger/plugin').before({}, program)]}),
和ts-jest(e2e)
要运行e2e测试,ts-jest在内存汇总编译源码,这意味着不使用Nest Cli编译,不应用任何插件或AST转换,要使用插件,在e2e测试目录下创建以下文件:
const transformer = require('@nestjs/swagger/plugin');module.exports.name = 'nestjs-swagger-transformer';// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changesmodule.exports.version = 1;module.exports.factory = (cs) => {return transformer.before({// @nestjs/swagger/plugin options (can be empty)},cs.tsCompiler.program,);};
在jest配置文件中引入AST变换。默认在(启动应用中),e2e测试配置文件在测试目录下,名为jest-e2e.json。
{... // other configuration"globals": {"ts-jest": {"astTransformers": {"before": ["<path to the file created above>"],}}}}
其他特性
全局前缀
要忽略一个通过setGlobalPrefix()配置的全局前缀, 使用ignoreGlobalPrefix:
const document = SwaggerModule.createDocument(app, options, {ignoreGlobalPrefix: true,});
多重声明
Swagger模块提供了一个支持多重声明的方法,也就是说可以在多个终端提供多个界面和多个文档。
要支持多重声明,首先在模块中要进行声明,在createDocument()方法中传递第3个参数,extraOptions,这是个包含一个叫做include名称的属性,该属性提供了一个由模块组成的数组。
可以如下配置多重声明:
import { NestFactory } from '@nestjs/core';import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';import { AppModule } from './app.module';async function bootstrap() {const app = await NestFactory.create(AppModule);/*** createDocument(application, configurationOptions, extraOptions);** createDocument method takes an optional 3rd argument "extraOptions"* which is an object with "include" property where you can pass an Array* of Modules that you want to include in that Swagger Specification* E.g: CatsModule and DogsModule will have two separate Swagger Specifications which* will be exposed on two different SwaggerUI with two different endpoints.*/const options = new DocumentBuilder().setTitle('Cats example').setDescription('The cats API description').setVersion('1.0').addTag('cats').build();const catDocument = SwaggerModule.createDocument(app, options, {include: [CatsModule],});SwaggerModule.setup('api/cats', app, catDocument);const secondOptions = new DocumentBuilder().setTitle('Dogs example').setDescription('The dogs API description').setVersion('1.0').addTag('dogs').build();const dogDocument = SwaggerModule.createDocument(app, secondOptions, {include: [DogsModule],});SwaggerModule.setup('api/dogs', app, dogDocument);await app.listen(3000);}bootstrap();
现在可以使用以下命令启动服务器:
$ npm run start
访问http://localhost:3000/api/cats可以看到cats的Swagger界面,
访问http://localhost:3000/api/dogs可以看到dogs的Swagger界面。
迁移指南
如果你在使用@nestjs/swagger@3.*, 注意在4.0版本中有以下破坏性变化或者更改。
破坏性变化
以下装饰器被改变/重命名
@ApiModelProperty现在是@ApiProperty@ApiModelPropertyOptional现在是@ApiPropertyOptional@ApiResponseModelProperty现在是@ApiResponseProperty@ApiImplicitQuery现在是@ApiQuery@ApiImplicitParam现在是@ApiParam@ApiImplicitBody现在是@ApiBody@ApiImplicitHeader现在是@ApiHeader@ApiOperation({ title: 'test' })现在是@ApiOperation({ summary: 'test' })@ApiUseTags现在是@ApiTags
DocumentBuilder的破坏性更新(升级了方法签名):
- addTag
- addBearerAuth
- addOAuth2
- setContactEmail
现在是setContact - setHost has been removed
- setSchemes has been removed (使用`addServer instead, e.g., addServer(‘http://‘))
新方法
添加了以下新方法:
- addServer
- addApiKey
- addBasicAuth
- addSecurity
- addSecurityRequirements
译者署名
| 用户名 | 头像 | 职能 | 签名 |
|---|---|---|---|
