NestJS 集成 Swagger + Apifox:一键生成 API 文档,告别接口联调纠纷

791 阅读3分钟

使用

访问 http://localhost:3000/api 查看 Swagger UI。

  1. 安装
pnpm add @nestjs/swagger swagger-ui-express

api 介绍

注册时配置

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('名称')
    .setDescription(
      '描述:<a href="http://localhost:3000/api-json">默认 json 链接</a>',
    )
    .setVersion('1.0.1')
    .setOpenAPIVersion('3.1.0')
    // 添加标签
    .addTag('users')
    .addTag('app')
    // 添加授权
    .addBearerAuth()
    .build();
  // 创建文档
  const document = SwaggerModule.createDocument(app, config);
  // 设置文档路径 为 api
  SwaggerModule.setup('api', app, document);

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

控制器配置

@ApiTags

添加 tag,和创建时的 addTag效果一样。如果要添加多余参数去 注册配置 addTag

@ApiTags('users')
  @Controller()
  export class AppController {}

接口配置

@ApiOperation 描述

  • summary: 描述
  • tags:添加到对应的 tag
  • description: 描述
@Get()
  @ApiOperation({ summary: '你好' })
  getHello(): string {
  return this.appService.getHello();
}

@ApiQuery 查询参数 , @ApiParam路径参数

路径参数没有默认值,直接使用 example

@Get('users')
  @ApiQuery({
    name: 'id',
    description: '用户id',
    required: false,
    example: '123',
    default: '默认',
  })
  getUsers(@Query('id') id: string): string {
  return this.appService.getHello();
}

@ApiBody 请求体

注意:

  1. 最好是定义 dto
  2. schema 和 type 不能同时使用

@ApiBody({
  type: User,
  description: '枚举:1:张三,2:李四,3:王五',
  // 不能和type同时使用
  // schema: {
  //   type: 'object',
  //   properties: {
  //     name: { type: 'string', example: '张三' },
  //     email: { type: 'string', example: 'zhangsan@example.com' },
  //   },
  // },
  required: false,
  isArray: false,
})

@ApiResponse 响应

注意:

  1. content 和 schema 不能同时使用
  2. content 和 type 不能同时使用

@ApiResponse({
  status: 200,
  description: '返回成功',
  content: {
    'application/json': {
      schema: {
        type: 'object',
        properties: {
          status: { type: 'number', example: 200 },
          message: { type: 'string', example: '返回成功' },
        },
      },
    },
    'application/text': {
      schema: {
        type: 'string',
        example: '返回成功',
      },
    },
    // 引用 User 未定义的类型(dto) 装饰器 
    'application/json-test': {
      schema: {
        $ref: '#/components/schemas/User',
      },
    },
  },
  // 不能和content同时使用
  // schema: {
  //   type: 'object',
  //   properties: {
  //     status: { type: 'number' },
  //     message: { type: 'string' },
  //   },
  // },
})

类型配置 DTO

@ApiProperty

enum UserEnum {
  ZHANG_SAN = 1,
  LI_SI = 2,
  WANG_WU = 3,
}
class Info {
  @ApiProperty({
    description: '姓名',
    example: '张三',
  })
  name: string;

  @ApiProperty({
    description: '邮箱',
    example: 'zhangsan@example.com',
  })
  email: string;
}

export class User {
  @ApiProperty({
    description: 'The email of the user',
    example: 'john.doe@example.com',
  })
  email: string;

  @ApiProperty({
    description: '枚举:1:张三,2:李四,3:王五',
    example: UserEnum.ZHANG_SAN,
    enum: UserEnum,
    name: 'name',
    required: true,
  })
  name: UserEnum;

  // 定义一个复杂类型
  @ApiProperty({
    description: '复杂类型',
    type: Info,
    example: { name: '张三', email: 'zhangsan@example.com' },
  })
  complex: Info;
}

配置 Swagger JSON 文件 链接

默认是 http://localhost:3000/api-json

SwaggerModule.setup('swagger', app, document, {
  // 配置 http://localhost:3000/swagger/json
  jsonDocumentUrl: 'swagger/json',
});

实例

  1. 配置 Swagger
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('Your API Title')
    .setDescription('Your API Description')
    .setVersion('1.0')
    .addTag('users')
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();
  1. 使用 Swagger 装饰器

import {
  Controller,
  Get,
  Post,
  Body,
  Put,
  Delete,
  Param,
} from '@nestjs/common';
import { AppService } from './app.service';
import { ApiTags, ApiOperation, ApiResponse, ApiBody } from '@nestjs/swagger';

import { ApiProperty } from '@nestjs/swagger';

export class User {
  @ApiProperty({ description: 'The name of the user', example: 'John Doe' })
  name: string;

  @ApiProperty({
    description: 'The email of the user',
    example: 'john.doe@example.com',
  })
  email: string;
}

@ApiTags('users')
  @Controller()
  export class AppController {
    constructor(private readonly appService: AppService) {}

    @Get()
    @ApiOperation({ summary: 'Get hello message' })
    @ApiResponse({ status: 200, description: 'Returns a hello message' })
    getHello(): string {
      return this.appService.getHello();
    }

    @Post()
    @ApiOperation({ summary: 'Create a new user' })
    @ApiBody({ type: User })
    @ApiResponse({
      status: 201,
      description: 'The user has been successfully created.',
    })
    createUser(@Body() user: User): User {
      return this.appService.createUser(user);
    }

    @Put()
    @ApiOperation({ summary: 'Update an existing user' })
    @ApiBody({ type: User })
    @ApiResponse({
      status: 200,
      description: 'The user has been successfully updated.',
    })
    updateUser(@Body() user: User): User {
      return this.appService.updateUser(user);
    }

    @Delete(':id')
    @ApiOperation({ summary: 'Delete a user by ID' })
    @ApiResponse({
      status: 200,
      description: 'The user has been successfully deleted.',
    })
    deleteUser(@Param('id') id: string): string {
      return this.appService.deleteUser(id);
    }
  }

创建并一键导入 apifox

  1. 找到 Swagger JSON 文件,默认:http://localhost:3000/api-json 可以在创建的时候 SwaggerModule.set 定义。
  2. 在 apifox 中创建好一个项目

  1. 然后导入

  1. 把 url 输入,也可设置定时导入,可自行操作

导入后请求、响应、示例,结构都有了

后面可以写一个通用的 swagger to ts 来直接转换为代码调用,省去对接口的流程,项目直接使用!