全栈第一步 - 使用NestJs搭建服务端应用 -- 二 (引入Swagger生成接口文档)

1,731 阅读3分钟

简介

OpenAPI(Swagger)规范是一种用于描述 RESTful API 的强大定义格式。它可以做到生成各种格式的接口文档,生成多种语言的客户端和服务端的代码,以及在线接口调试页面等等。降低了前后端交流的成本。

安装

Nest.js提供了一个专门的模块来使用它,我们可以直接在项目中使用指令来安装

# yarn
yarn add @nestjs/swagger swagger-ui-express

# npm
npm install --save @nestjs/swagger swagger-ui-express

初始化 引导(Bootstrap)

安装成功后,我们需要打开main.ts来初始化Swagger,在main.ts中添加如下代码

import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

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

  const options = new DocumentBuilder()
    // 标题
    .setTitle('vite-app-api')
    // 描述
    .setDescription('使用NestJs搭建的服务端应用')
    // 版本号
    .setVersion('1.0')
    // 标签,此处暂时不需要
    // .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, options);
  // 因为api我们已经留给接口前缀了,这里修改为api-docs
  SwaggerModule.setup('api-docs', app, document);

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

启动项目,先访问看下

image.png

可以看到,我们项目中目前的接口已经被扫描出来了。但是目前接口的描述还是空的。这里需要手动添加一下

配置

接口

首先我们需要把接口根据业务区分下,打上对应的标签。 打开user.controller.ts

@Controller('user')
// 在这里给控制器添加标签
@ApiTags('用户操作')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Post('register')
  register(@Body() user: any) {
    return this.userService.register(user);
  }
}

再看下swagger

image.png

这样区分一下,对于调试和维护会非常方便

参数

首先,补充一下入参的类型,看过文档的同学都会看到,他们建议使用class而不是interface来定义类型。原文是这么说的:

首先(如果您使用 TypeScript),我们需要确定 DTO(数据传输对象)模式。DTO是一个对象,它定义了如何通过网络发送数据。我们可以通过使用 TypeScript 接口(Interface)或简单的类(Class)来定义 DTO 模式。有趣的是,我们在这里推荐使用类。为什么?类是 JavaScript ES6 标准的一部分,因此它们在编译后的 JavaScript 中被保留为实际实体。另一方面,由于 TypeScript 接口在转换过程中被删除,所以 Nest 不能在运行时引用它们。这一点很重要,因为诸如管道(Pipe)之类的特性为在运行时访问变量的元类型提供更多的可能性。

我们在src下新建types文件夹,并创建一个system-user.dto.ts文件

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

export class RegisterUserDto {
  // 给参数添加描述
  @ApiProperty({ description: '用户名' })
  userName: string;
  @ApiProperty({ description: '密码' })
  pwd: string;
  @ApiProperty({ description: '确认密码' })
  confirmPwd: string;
}

然后在我们的控制器中引入并应用它。

// user.controller.ts

import { RegisterUserDto } from '@/types/system-user.dto'; //BTW 这里我配置了路径别名,具体配置方法这里就不描述了,很简单

@Controller('user')
@ApiTags('用户操作')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Post('register')
  // 使用此装饰器来添加接口描述
  @ApiOperation({ summary: '注册新用户' })
  register(@Body() user: RegisterUserDto): boolean {
    return this.userService.register(user);
  }
}

再看下网页

示例数据.png

参数说明.png

Swagger为我们生成了接口入参描述以及示例数据,我们也可以直接在这里测试下接口

点击try it out,它会以该示例数据像接口发送请求,当然,此处也可以自定义数据

image.png

发送后回显了curl、请求url以及相应体。。

  • to be continued~~