天天看點

nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔

swagger

*由于最近新版@nestjs/swagger4.*的更新,使用的注解也發生了一些改動,具體可以檢視

@nestjs/swagger官方位址

swagger:一個功能強大的高清格式來描述

RESTful API

。Nest提供了專用的子產品來使用它

1. 安裝swagger

yarn add @nestjs/swagger swagger-ui-express --save
           
如果使用fastify,則必須安裝fastify-swagger而不是swagger-ui-express:
yarn add @nestjs/swagger fastify-swagger --save
           

2.配置文檔格式資訊

// main.ts 中配置
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
// api文檔插件
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
const app = await NestFactory.create<NestExpressApplication>(AppModule);
// DocumentBuilder是一個輔助類,有助于結構的基本檔案SwaggerModule。它包含幾種方法,可用于設定諸如标題,描述,版本等屬性。
  const options = new DocumentBuilder()
    .setTitle('nest入門接口标題')
    .setDescription('使用nest書寫的常用性接口') // 文檔介紹
    .setVersion('1.0.0') // 文檔版本
    .addTag('使用者,安全') // 每個tag标簽都可以對應着幾個@ApiUseTags('使用者,安全') 然後被ApiUseTags注釋,字元串一緻的都會變成同一個标簽下的
    // .setBasePath('http://localhost:5000')
    .build();
  // 為了建立完整的文檔(具有定義的HTTP路由),我們使用類的createDocument()方法SwaggerModule。此方法帶有兩個參數,分别是應用程式執行個體和基本Swagger選項。
  const document = SwaggerModule.createDocument(app, options);
   // 最後一步是setup()。它依次接受(1)裝入Swagger的路徑,(2)應用程式執行個體, (3)描述Nest應用程式的文檔。
  SwaggerModule.setup('/api', app, document);
   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/
nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔
nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔
nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔

然後傳回正确的狀态和資料,文檔都無需自己手寫,減少不少的文檔編輯量

定義控制器時,SwaggerModule尋找所有的使用@Body(),@Query()以及@Param()在路由處理器裝飾。是以,可以建立有效的文檔。

2.1 我們建立user檔案夾,存放user相關的module,controller,service,代碼如下:

// user.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class UserService {
    public getUser(id: string): string {
        return `使用者的id:${id}`;
    }
}
           
// user.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { UserService } from './user.service';

@Controller('/user')
export class UserController {
    constructor(private userService: UserService) { }
    @Get('/get/:id')
    public getUser(@Param('id') id: string): string {
        return this.userService.getUser(id);
    }
}

           
// user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
    providers: [UserService],
    controllers: [UserController],
})
export class UserModule { }
           
// user.controller.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { UserController } from './user.controller';
import { UserService } from './user.service';

describe('UserController', () => {
  let userController: UserController;

  beforeEach(async () => {
    const app: TestingModule = await Test.createTestingModule({
      controllers: [UserController],
      providers: [UserService],
    }).compile();

    userController = app.get<UserController>(UserController);
  });

  describe('user', () => {
    it('should return "使用者的id: xxx"', () => {
      expect(userController.getUser('111')).toBe('使用者的id:111');
    });
  });
});
           
這時候我們看一下swagger的文檔,發現多了/user/get/{id}這個get請求的路由。
nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔

當然,這樣往往是不足夠的,swagger還提供了修飾dto、參數、請求響應等配置

3.swagger的配置裝飾器

swagger的配置裝飾器都是以@api開頭

3.1 ApiTags裝飾器,讓對應的子產品分類到對應的标簽當中
在user.controller.ts中添加該裝飾器在控制器類上
import { ApiTags } from '@nestjs/swagger';
import { Controller, Get, Query } from '@nestjs/common';
@ApiTags('使用者,安全')
@Controller('/user')
export class UserController {
	//...
}
           

然後對應的這個控制器就配置設定到該組

nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔
3.2 ApiQuery、ApiBody、ApiParam、ApiHeader、ApiHeaders

除了ApiImplicitHeaders之外,其它的接收一個對象,對象類型如下:

name: string; // 該資料的名稱,比如:id可以寫使用者id或者id
description?: string; // 簡介
required?: boolean; // 是否是必須的
type?: any; // 類型
isArray?: boolean; // 是否是數組
enum?: SwaggerEnumType; // 枚舉類型
collectionFormat?: "csv" | "ssv" | "tsv" | "pipes" | "multi";
           
而ApiHeaders需要的對象隻有三個參數
name: string;
 description?: string;
 required?: boolean;
           

修改user.controller.ts檔案成如下代碼:

import { Controller, Get, Param, Query } from '@nestjs/common';
import { ApiTags, ApiParam, ApiQuery, ApiHeader } from '@nestjs/swagger';
import { UserService } from './user.service';

@ApiTags('使用者,安全')
@Controller('/user')
export class UserController {
    constructor(private userService: UserService) { }
    @Get('/get/:id')
    @ApiParam({
        name: 'id',
        description: '這是使用者id',
    })
    @ApiQuery({
        name: 'role',
        description: '這是需要傳遞的參數',
    })
    @ApiHeader({
        name: 'authoriation',
        required: true,
        description: '本次請求請帶上token',
    })
    public getUser(@Param('id') id: string, @Query('role') role: string): string {
        return this.userService.getUser(id);
    }
}

           
儲存,重新整理頁面
nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔

會發現變成,對應的字段有對應的描述資訊

nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔

我們隻需要在編寫接口的同時添加swagger提供裝飾器即可,無需開發過後再回來編寫文檔

3.3 還有就是dto的參數配置ApiProperty

// user.controller.ts 加上如下方法
    @Post('/add')
    public addUser(@Body() user: User) {
        return user;
    }
           
建立一個User對象
// User.ts
import { ApiProperty } from '@nestjs/swagger';

export class User {
    @ApiProperty({
        description: '使用者名',
    })
    username: string;
    @ApiProperty({
        description: '密碼',
    })
    password: string;
}
           
這時候的文檔
nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔

ApiProperty可以接受的對象配置參數有許多,具體可以參考官方

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

當參數是數組的情況下,我們可以這樣配置@ApiProperty({ type: [String] })

3.4 還有就是ApiResponse,用來裝飾方法
@ApiResponse({ status: 401, description: '權限不足'})
	@Post('/add')
	public addUser(@Body() user: User) {
	   return user;
	}
           
nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔

nestjs還内置了大量的相關http狀态碼的描述,具體可以參照官方

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

3.5 ApiImplicitFile 可以用于檔案上傳的文檔測試

例如在addUser方法加上該裝飾器

@ApiResponse({ status: 401, description: '權限不足'})
    @ApiImplicitFile({
        name: '頭像',
        description: '上傳頭像',
        required: false,
    })
    @Post('/add')
    public addUser(@Body() user: User) {
        return user;
    }
           

這時候,我們可以看見文檔就是這樣的:

nodejs企業級開發架構nest學習總結 - 7.NestJS入門swagger,快速搭建restfulApi文檔
具體使用還需要結合實際,以上全部裝飾器都來自@nestjs/swagger
如果需要繼續深入,可以觀看官方文檔的案例

4. 多個swagger文檔,有時候我們需要分為前台接口和背景接口的情況下,我們可以編寫多個文檔

修改,把上面的文檔拆分成兩個文檔
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { UserModule } from './user/user.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const options = new DocumentBuilder()
    .setTitle('使用者資訊文檔')
    .setDescription('用于使用者資訊的增删改查')
    .setVersion('1.0')
    .addTag('使用者,安全')
    .build();

  const userDocument = SwaggerModule.createDocument(app, options, {
    include: [UserModule], // 包含的子產品
  });
  SwaggerModule.setup('api/user', app, userDocument);

  const secondOptions = new DocumentBuilder()
    .setTitle('整體文檔')
    .setDescription('包含了測試文檔和前台應用文檔')
    .setVersion('1.0')
    .addTag('使用者,安全')
    .build();

  const appDocument = SwaggerModule.createDocument(app, secondOptions, {
    include: [AppModule, UserModule],
  });
  SwaggerModule.setup('api', app, appDocument);

  await app.listen(3000);
}
bootstrap();

           

這時候,我們的文檔就分成了 http://localhost:3000/api 這個整體文檔和 使用者子產品的文檔 http://localhost:3000/api/user

我們發現http://localhost:3000/api和前面的一緻,而http://localhost:3000/api/user隻有使用者子產品的文檔

繼續閱讀