返回介绍

接入 Swagger 接口文档

发布于 2024-01-18 22:07:39 字数 6153 浏览 0 评论 0 收藏 0

  • 优点:不用写接口文档,在线生成,自动生成,可操作数据库,完美配合 dto
  • 缺点:多一些代码,显得有点乱,习惯就好
yarn add @nestjs/swagger swagger-ui-express -D
// main.ts
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

async function bootstrap() {
  // 创建实例
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  
  // 创建接口文档服务
  const options = new DocumentBuilder()
    .addBearerAuth() // token 认证,输入 token 才可以访问文档
    .setTitle('接口文档')
    .setDescription('接口文档介绍') // 文档介绍
    .addServer('http://localhost:9000', '开发环境')
    .addServer('https://test.com/release', '正式环境')
    .setVersion('1.0.0') // 文档版本
    .setContact('poetry', '', 'test@qq.com')
    .build();
  // 为了创建完整的文档(具有定义的 HTTP 路由),我们使用类的 createDocument() 方法 SwaggerModule。此方法带有两个参数,分别是应用程序实例和基本 Swagger 选项。
  const document = SwaggerModule.createDocument(app, options, {
    extraModels: [], // 这里导入模型
  });
  // 启动 swagger
  SwaggerModule.setup('api-docs', app, document); // 访问路径 http://localhost:9000/api-docs
  
  // 启动端口
  const PORT = process.env.PORT || 9000;
  await app.listen(PORT, () =>
    Logger.log(`服务已经启动 http://localhost:${PORT}`),
  );
}
bootstrap();

swagger 装饰器

https://swagger.io/

@ApiTags('user')   // 设置模块接口的分类,不设置默认分配到 default
@ApiOperation({ summary: '标题', description: '详细描述'})  // 单个接口描述

// 传参
@ApiQuery({ name: 'limit', required: true})    // query 参数
@ApiQuery({ name: 'role', enum: UserRole })    // query 参数
@ApiParam({ name: 'id' })      // parma 参数
@ApiBody({ type: UserCreateDTO, description: '输入用户名和密码' })   // 请求体

// 响应
@ApiResponse({
    status: 200,
    description: '成功返回 200,失败返回 400',
    type: UserCreateDTO,
})

// 验证
@ApiProperty({ example: 'Kitty', description: 'The name of the Cat' })
name: string;

controller 引入 @nestjs/swagger , 并配置 @ApiBody()@ApiParam() 不写也是可以的

user.controller.ts

import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Query,
  Param,
  Delete,
  HttpCode,
  HttpStatus,
  ParseIntPipe,
} from '@nestjs/common';
import {
  ApiOperation,
  ApiTags,
  ApiQuery,
  ApiBody,
  ApiResponse,
} from '@nestjs/swagger';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('user')
@ApiTags('user')  // 设置分类
export class UserController {
  constructor(private readonly userService: UserService) { }

  @Post()
  @ApiOperation({ summary: '创建用户', description: '创建用户' })  // 该接口
  @HttpCode(HttpStatus.OK)
  async create(@Body() user: CreateUserDto) {
    return await this.userService.create(user);
  }

  @Get()
  @ApiOperation({ summary: '查找全部用户', description: '创建用户' })
  @ApiQuery({ name: 'limit', required: true })  请求参数
  @ApiQuery({ name: 'offset', required: true }) 请求参数
  async findAll(@Query() query) {
    console.log(query);
    const [data, count] = await this.userService.findAll(query);
    return { count, data };
  }

  @Get(':id')
  @ApiOperation({ summary: '根据 ID 查找用户' })
  async findOne(@Param('id', new ParseIntPipe()) id: number) {
    return await this.userService.findOne(id);
  }

  @Patch(':id')
  @ApiOperation({ summary: '更新用户' })
  @ApiBody({ type: UpdateUserDto, description: '参数可选' })  请求体
  @ApiResponse({   响应示例
    status: 200,
    description: '成功返回 200,失败返回 400',
    type: UpdateUserDto,
  })
  async update(
    @Param('id', new ParseIntPipe()) id: number,
    @Body() user: UpdateUserDto,
  ) {
    return await this.userService.update(id, user);
  }

  @Delete(':id')
  @ApiOperation({ summary: '删除用户' })
  async remove(@Param('id', new ParseIntPipe()) id: number) {
    return await this.userService.remove(id);
  }
}

编写 dto,引入 @nestjs/swagger

创建

import { IsNotEmpty, MinLength, MaxLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class CreateUserDto {
  @ApiProperty({ example: 'kitty', description: '用户名' })  添加这里即可
  @IsNotEmpty({ message: '用户名不能为空' })
  username: string;

  @ApiProperty({ example: '12345678', description: '密码' })
  @IsNotEmpty({ message: '密码不能为空' })
  @MinLength(6, {
    message: '密码长度不能小于 6 位',
  })
  @MaxLength(20, {
    message: '密码长度不能超过 20 位',
  })
  password: string;
}

更新

import {
  IsEnum,
  MinLength,
  MaxLength,
  IsOptional,
  ValidateIf,
  IsEmail,
  IsMobilePhone,
} from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';

export class UpdateUserDto {
  @ApiProperty({ description: '用户名', example: 'kitty', required: false })  不是必选的
  @IsOptional()
  username: string;

  @ApiProperty({ description: '密码', example: '12345678', required: false })
  @IsOptional()
  @MinLength(6, {
    message: '密码长度不能小于 6 位',
  })
  @MaxLength(20, {
    message: '密码长度不能超过 20 位',
  })
  password: string;

  @ApiProperty({
    description: '邮箱',
    example: 'llovenest@163.com',
    required: false,
  })
  @IsOptional()
  @IsEmail({}, { message: '邮箱格式错误' })
  @ValidateIf((o) => o.username === 'admin')
  email: string;

  @ApiProperty({
    description: '手机号码',
    example: '13866668888',
    required: false,
  })
  @IsOptional()
  @IsMobilePhone('zh-CN', {}, { message: '手机号码格式错误' })
  mobile: string;

  @ApiProperty({
    description: '性别',
    example: 'female',
    required: false,
    enum: ['male', 'female'],
  })
  @IsOptional()
  @IsEnum(['male', 'female'], {
    message: 'gender 只能传入字符串 male 或 female',
  })
  gender: string;

  @ApiProperty({
    description: '状态',
    example: 1,
    required: false,
    enum: [0, 1],
  })
  @IsOptional()
  @IsEnum(
    { 禁用: 0, 可用: 1 },
    {
      message: 'status 只能传入数字 0 或 1',
    },
  )
  @Type(() => Number)
  status: number;
}

打开:localhost:3000/api-docs,开始测试接口

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文