当前位置:   article > 正文

nestjs 使用swagger 搭建接口文档_nestjs swagger

nestjs swagger

NestJS入门swagger,快速搭建restfulApi文档

2020-01-11 • admin • NestJS入门swagger,快速搭建restfulApi文档已关闭评论条评论 • 550 次浏览

 

swagger

*由于最近新版@nestjs/swagger4.*的更新,使用的注解也发生了一些改动,具体可以查看

@nestjs/swagger官方地址

swagger:一个功能强大的高清格式来描述RESTful API。Nest提供了专用的模块来使用它

1. 安装swagger

yarn add @nestjs/swagger swagger-ui-express --save
 
  • 1

如果使用fastify,则必须安装fastify-swagger而不是swagger-ui-express:

yarn add @nestjs/swagger fastify-swagger --save
 
  • 1

2.配置文档格式信息

  1. // main.ts 中配置
  2. import { NestFactory } from '@nestjs/core';
  3. import { NestExpressApplication } from '@nestjs/platform-express';
  4. // api文档插件
  5. import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
  6. const app = await NestFactory.create<NestExpressApplication>(AppModule);
  7. // DocumentBuilder是一个辅助类,有助于结构的基本文件SwaggerModule。它包含几种方法,可用于设置诸如标题,描述,版本等属性。
  8. const options = new DocumentBuilder()
  9. .setTitle('nest入门接口标题')
  10. .setDescription('使用nest书写的常用性接口') // 文档介绍
  11. .setVersion('1.0.0') // 文档版本
  12. .addTag('用户,安全') // 每个tag标签都可以对应着几个@ApiUseTags('用户,安全') 然后被ApiUseTags注释,字符串一致的都会变成同一个标签下的
  13. // .setBasePath('http://localhost:5000')
  14. .build();
  15. // 为了创建完整的文档(具有定义的HTTP路由),我们使用类的createDocument()方法SwaggerModule。此方法带有两个参数,分别是应用程序实例和基本Swagger选项。
  16. const document = SwaggerModule.createDocument(app, options);
  17. // 最后一步是setup()。它依次接受(1)装入Swagger的路径,(2)应用程序实例, (3)描述Nest应用程序的文档。
  18. SwaggerModule.setup('/api', app, document);
  19. await app.listen(5000);
 

1.先通过DocumentBuilder实例来设置文档的配置选项,例如版本、标题、文档介绍、多个标签等

2.然后通过@nestjs/swagger模块提供的SwaggerModule的createDocument方法创建文档,传递整个app(应用程序实例)为第一个参数,第二个参数就是1配置号的文档选项

3.第三步是通过SwaggerModule的setup方法出口创建文档的url,它依次接受(1)装入Swagger的路径,(2)应用程序实例, (3)描述Nest应用程序的文档。

这时候会变成默认的配置文档选项

这时候启动默认初始化的项目,访问http://localhost:3000/api/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

然后返回正确的状态和数据,文档都无需自己手写,减少不少的文档编辑量
定义控制器时,SwaggerModule寻找所有的使用@Body(),@Query()以及@Param()在路由处理器装饰。因此,可以创建有效的文档。

2.1 我们创建user文件夹,存放user相关的module,controller,service,代码如下:

  1. // user.service.ts
  2. import { Injectable } from '@nestjs/common';
  3. @Injectable()
  4. export class UserService {
  5. public getUser(id: string): string {
  6. return `用户的id:${id}`;
  7. }
  8. }
 
  •  
  1. // user.controller.ts
  2. import { Controller, Get, Param } from '@nestjs/common';
  3. import { UserService } from './user.service';
  4. @Controller('/user')
  5. export class UserController {
  6. constructor(private userService: UserService) { }
  7. @Get('/get/:id')
  8. public getUser(@Param('id') id: string): string {
  9. return this.userService.getUser(id);
  10. }
  11. }
 
  •  
  1. // user.module.ts
  2. import { Module } from '@nestjs/common';
  3. import { UserService } from './user.service';
  4. import { UserController } from './user.controller';
  5. @Module({
  6. providers: [UserService],
  7. controllers: [UserController],
  8. })
  9. export class UserModule { }
 
  •  
  1. // user.controller.spec.ts
  2. import { Test, TestingModule } from '@nestjs/testing';
  3. import { UserController } from './user.controller';
  4. import { UserService } from './user.service';
  5. describe('UserController', () => {
  6. let userController: UserController;
  7. beforeEach(async () => {
  8. const app: TestingModule = await Test.createTestingModule({
  9. controllers: [UserController],
  10. providers: [UserService],
  11. }).compile();
  12. userController = app.get<UserController>(UserController);
  13. });
  14. describe('user', () => {
  15. it('should return "用户的id: xxx"', () => {
  16. expect(userController.getUser('111')).toBe('用户的id:111');
  17. });
  18. });
  19. });
 
  •  

这时候我们看一下swagger的文档,发现多了/user/get/{id}这个get请求的路由。

在这里插入图片描述

当然,这样往往是不足够的,swagger还提供了修饰dto、参数、请求响应等配置

3.swagger的配置装饰器

swagger的配置装饰器都是以@api开头

3.1 ApiTags装饰器,让对应的模块分类到对应的标签当中

在user.controller.ts中添加该装饰器在控制器类上

  1. import { ApiTags } from '@nestjs/swagger';
  2. import { Controller, Get, Query } from '@nestjs/common';
  3. @ApiTags('用户,安全')
  4. @Controller('/user')
  5. export class UserController {
  6. //...
  7. }
 
  •  

然后对应的这个控制器就分配到该组

在这里插入图片描述

3.2 ApiQuery、ApiBody、ApiParam、ApiHeader、ApiHeaders

除了ApiImplicitHeaders之外,其它的接收一个对象,对象类型如下:

  1. name: string; // 该数据的名称,比如:id可以写用户id或者id
  2. description?: string; // 简介
  3. required?: boolean; // 是否是必须的
  4. type?: any; // 类型
  5. isArray?: boolean; // 是否是数组
  6. enum?: SwaggerEnumType; // 枚举类型
  7. collectionFormat?: "csv" | "ssv" | "tsv" | "pipes" | "multi";
 
  •  

而ApiHeaders需要的对象只有三个参数

  1. name: string;
  2. description?: string;
  3. required?: boolean;
 
  •  

修改user.controller.ts文件成如下代码:

  1. import { Controller, Get, Param, Query } from '@nestjs/common';
  2. import { ApiTags, ApiParam, ApiQuery, ApiHeader } from '@nestjs/swagger';
  3. import { UserService } from './user.service';
  4. @ApiTags('用户,安全')
  5. @Controller('/user')
  6. export class UserController {
  7. constructor(private userService: UserService) { }
  8. @Get('/get/:id')
  9. @ApiParam({
  10. name: 'id',
  11. description: '这是用户id',
  12. })
  13. @ApiQuery({
  14. name: 'role',
  15. description: '这是需要传递的参数',
  16. })
  17. @ApiHeader({
  18. name: 'authoriation',
  19. required: true,
  20. description: '本次请求请带上token',
  21. })
  22. public getUser(@Param('id') id: string, @Query('role') role: string): string {
  23. return this.userService.getUser(id);
  24. }
  25. }
 
  •  

保存,刷新页面

在这里插入图片描述
会发现变成,对应的字段有对应的描述信息
在这里插入图片描述
我们只需要在编写接口的同时添加swagger提供装饰器即可,无需开发过后再回来编写文档

3.3 还有就是dto的参数配置ApiProperty

  1. // user.controller.ts 加上如下方法
  2. @Post('/add')
  3. public addUser(@Body() user: User) {
  4. return user;
  5. }
 
  •  

创建一个User对象

  1. // User.ts
  2. import { ApiProperty } from '@nestjs/swagger';
  3. export class User {
  4. @ApiProperty({
  5. description: '用户名',
  6. })
  7. username: string;
  8. @ApiProperty({
  9. description: '密码',
  10. })
  11. password: string;
  12. }
 
  •  

这时候的文档

在这里插入图片描述

ApiProperty可以接受的对象配置参数有许多,具体可以参考官方

https://docs.nestjs.com/recipes/swagger

当参数是数组的情况下,我们可以这样配置@ApiProperty({ type: [String] })

3.4 还有就是ApiResponse,用来装饰方法

  1. @ApiResponse({ status: 401, description: '权限不足'})
  2. @Post('/add')
  3. public addUser(@Body() user: User) {
  4. return user;
  5. }
 
  •  

在这里插入图片描述

nestjs还内置了大量的相关http状态码的描述,具体可以参照官方https://docs.nestjs.com/recipes/swagger

3.5 ApiImplicitFile 可以用于文件上传的文档测试

例如在addUser方法加上该装饰器

  1. @ApiResponse({ status: 401, description: '权限不足'})
  2. @ApiImplicitFile({
  3. name: '头像',
  4. description: '上传头像',
  5. required: false,
  6. })
  7. @Post('/add')
  8. public addUser(@Body() user: User) {
  9. return user;
  10. }
 
  •  

这时候,我们可以看见文档就是这样的:
在这里插入图片描述

具体使用还需要结合实际,以上全部装饰器都来自@nestjs/swagger

如果需要继续深入,可以观看官方文档的案例

4. 多个swagger文档,有时候我们需要分为前台接口和后台接口的情况下,我们可以编写多个文档

修改,把上面的文档拆分成两个文档

  1. import { NestFactory } from '@nestjs/core';
  2. import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
  3. import { AppModule } from './app.module';
  4. import { UserModule } from './user/user.module';
  5. async function bootstrap() {
  6. const app = await NestFactory.create(AppModule);
  7. const options = new DocumentBuilder()
  8. .setTitle('用户信息文档')
  9. .setDescription('用于用户信息的增删改查')
  10. .setVersion('1.0')
  11. .addTag('用户,安全')
  12. .build();
  13. const userDocument = SwaggerModule.createDocument(app, options, {
  14. include: [UserModule], // 包含的模块
  15. });
  16. SwaggerModule.setup('api/user', app, userDocument);
  17. const secondOptions = new DocumentBuilder()
  18. .setTitle('整体文档')
  19. .setDescription('包含了测试文档和前台应用文档')
  20. .setVersion('1.0')
  21. .addTag('用户,安全')
  22. .build();
  23. const appDocument = SwaggerModule.createDocument(app, secondOptions, {
  24. include: [AppModule, UserModule],
  25. });
  26. SwaggerModule.setup('api', app, appDocument);
  27. await app.listen(3000);
  28. }
  29. bootstrap();

这时候,我们的文档就分成了 http://localhost:3000/api 这个整体文档和 用户模块的文档 http://localhost:3000/api/user

我们发现http://localhost:3000/api和前面的一致,而http://localhost:3000/api/user只有用户模块的文档

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/478660
推荐阅读
相关标签
  

闽ICP备14008679号