Swagger
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。Swagger 让部署管理和使用功能强大的 API 从未如此简单。
Midway 通过组件化的形式来支持 swagger 能力。
一、例子
点此 访问示例库
$ npm install
$ npm run dev
然后访问:http://127.0.0.1:7001/swagger-ui/index.html
二、使用方法
2.1 安装
安装依赖。
npm install @midwayjs/swagger@1 --save
npm install swagger-ui-dist --save-dev
如果想要在服务器上输出 swagger API 页面,则需要将 swagger-ui-dist 安装到依赖中。
npm install swagger-ui-dist --save
2.2 配置
在 configuration.ts 中增加组件。
import { Configuration } from '@midwayjs/decorator';
import * as swagger from '@midwayjs/swagger';
@Configuration({
  imports: [swagger],
})
export class ContainerConfiguration {}
可以配置启用的环境,比如下面的代码指的是“只在 local 环境下启用”。
import { Configuration } from '@midwayjs/decorator';
import * as swagger from '@midwayjs/swagger';
@Configuration({
  imports: [
    {
      component: swagger,
      enabledEnvironment: ['local'],
    },
  ],
})
export class ContainerConfiguration {}
2.3 使用
直接启动即可,由于通过元数据进行了分析,默认情况下,可以直接获取到当前的参数,类型,名称,依赖关系等。
访问:http://127.0.0.1:7001/swagger-ui/index.html 拿到 swagger UI 界面。 访问:http://127.0.0.1:7001/swagger-ui/json 拿到 swagger json 结构。
三、示例
3.1 描述请求
通过 summary 和 description 方法,我们可以对整个接口进行描述。
import { CreateApiDoc } from '@midwayjs/swagger'
@CreateApiDoc()
  .summary('get user')
  .description('This is a open api for get user')
  .build()
@Get('/:userId')
async getUser(@Param() userId: number, @Query() name?: string) {
  return {
    name: 'harry',
    age: 18
  };
}
3.2 参数描述
通过 param 方法可以描述接口的参数,按顺序描述参数。如果有多个参数,则可以调用多次。以我们的示例为例,有两个参数, userId 和 name 。
param 方法的定义如下。
param(description: Partial<APIParamFormat>): SwaggerAPI;
param(description: string, options?: Partial<APIParamFormat>): SwaggerAPI;
在最简单的情况下,我们可以直接写参数的描述,同时,会自动分析出参数的类型,比如路由中的参数、请求中的参数等。
@CreateApiDoc()
	.param('user id')
	.param('user name')
  .build()
@Get('/:userId')
async getUser(@Param() userId: number, @Query() name?: string) {
  return {
    name: 'harry',
    age: 18
  };
}
在更为复杂的情况下,参数可以更加精确的描述。
export interface APIParamFormat {
  name: string; // 参数名
  description: string; // 参数描述
  required: boolean; // 参数是否必须
  deprecated: boolean; // 参数是否废弃
  allowEmptyValue: boolean; // 参数是否允许控制
  example: any; // 参数的示例
}
下面是参数的示例,有两种方式去具体描述参数。
@CreateApiDoc()
.summary('get user')
.description('This is a open api for get user')
.param('user id', {
  required: true,
  example: '123456'
})
.param({
  description: 'This is a user name'
})
.build()
@Get('/:userId')
async getUser(@Param() userId: number, @Query() name?: string) {
  return {
    name: 'harry',
    age: 18
  };
}
3.3 返回值描述
一个接口会有多种返回值的可能性,可以调用多次 respond 方法来描述不同的返回结果。
响应的接口描述如下。
respond(
  status: number,
  description?: string,
  respondType?: string,
  options?: Partial<APIResponseFormat>
): SwaggerAPI;
export interface APIResponseFormat {
  status: string;
  description: string;
  headers: any;
  example: any;
}
参数分为四个部分,除了状态码,其他都是可选参数,下面的示例展示了多种不同的返回描述。
@CreateApiDoc()
.summary('get user')
.description('This is a open api for get user')
.respond(200)
.respond(302, 'redirect to another URL')
.respond(201, 'response a text data', 'text', {
  headers: {
    'x-schema': {
      description: 'set a schema header',
      type: 'string'
    }
  },
  example: 'this is a reponse data'
})
.respond(500, 'error in response', 'json', {
  example: {
    a: 1
  }
})
.build()
你可以直接设置一个状态码,也可以在设置状态码之后,紧跟着设置描述,以及返回的 header,数据类型和示例。
展示的效果为
3.4 通用描述
可以通过在 Controller 装饰器和 Get 等路由装饰器上简单的增加描述信息。
控制器分组和描述
@Controller('/', { tagName: 'Custom Group', description: 'Home Router' })
export class HomeController {}
路由描述
@Get('/', {summary: 'Main Page', description: 'This is a home router'})
async home() {
  return 'Hello Midwayjs!';
}
增强的接口描述信息(进阶模式)
如果需要增加细节描述字段,则增加了 @CreateApiDoc 装饰器,用于定义描述,包括入参和出参。整个装饰器设计为链式调用,方便 IDE 获取到对应的方法和参数定义。
我们以一个接口为例。注意, @CreateApiDoc  装饰器最后需要跟一个 build  方法作为结尾。
完整的示例
import { CreateApiDoc, CreateApiPropertyDoc } from '@midwayjs/swagger';
export class UserDTO {
  @CreateApiPropertyDoc('user name')
  @Rule(RuleType.string().required())
  name: string;
  @CreateApiPropertyDoc('user age')
  @Rule(RuleType.number())
  age: number;
}
@Provide()
@Controller('/user')
export class UserController {
  @Inject()
  ctx: IMidwayKoaContext;
  @Inject()
  userService: UserService;
  @(CreateApiDoc()
    .summary('get user')
    .description('This a a open api for get user')
    .param('user id', {
      required: true,
      example: 2,
    })
    .param('user name')
    .respond(200, 'success', 'text', {
      example: 'hello world',
    })
    .respond(500, 'throw error')
    .build())
  @Get('/:userId')
  async getUser(@Param() userId: number, @Query() name?: string) {
    return {
      name: 'harry',
      age: 18,
    };
  }
}
更多配置
可以修改默认的 Swagger 版本,描述等。这些配置可以在用户配置,比如 src/config/config.default.ts  中配置。
export const swagger = {
  title: 'midway-swagger',
  description: 'swagger-ui for midway api',
  version: '1.0.0',
  termsOfService: '',
  contact: {
    name: 'API Support',
    url: 'http://www.example.com/support',
    email: '[email protected]',
  },
  license: {
    name: 'Apache 2.0',
    url: 'https://www.apache.org/licenses/LICENSE-2.0.html',
  },
};
四、其他
midwayjs Swagger【增加返回数据的配置】https://www.yuque.com/kxuan/efuxvf/ute5ak