【前端监控系统开发实录】之使用 swagger 配置接口文档 | 青训营笔记

427 阅读4分钟

这是我参与「第四届青训营」笔记创作活动的的第8天

swagger 安装

后端项目的技术栈是 nodejs + koa ,因此使用yarn add koa2-swagger-ui swagger-jsdoc --save安装依赖。

swagger 配置

  1. 根目录下新建config目录,在该目录下新建swagger.ts文件:
const Router = require('koa-router');
const path = require('path');
const swaggerJSDoc = require('swagger-jsdoc');

const swaggerRouter = new Router({
    prefix: '/swagger' // 路由前缀
})
const swaggerDefinition = {
    info: {
        title: 'monitor-system-node API 接口文档',
        version: '1.0.0',
        description: '详细的接口文档'
    }
}
const options = {
    swaggerDefinition,
    apis: [path.join(__dirname, '../routes/doc/*.ts')] // 写有注解的router的存放地址
}
const swaggerSpec = swaggerJSDoc(options);
// 通过路由获取生成的注解文件
swaggerRouter.get('/swagger.json', async function (ctx: { set: (arg0: string, arg1: string) => void; body: any; }) {
    ctx.set('Content-Type', 'application/json')
    ctx.body = swaggerSpec
})

export default swaggerRouter;
  1. 在入口文件app.ts中引入:
import {koaSwagger} from "koa2-swagger-ui";
import swaggerRouter from './config/swagger';

app.use(swaggerRouter.routes()).use(swaggerRouter.allowedMethods())
const swaggerOption = {
    routePrefix: '/swagger', // host at /swagger instead of default /docs
    swaggerOptions: {
        url: '/swagger/swagger.json' // example path to json 其实就是之后swagger-jsdoc生成的文档地址
    }
}
app.use(koaSwagger(swaggerOption))
  1. 启动服务,访问地址http://localhost:8080/swagger(域名改成你自己的),可以看到如下页面,说明配置成功: image.png

编写接口文档

安装完 swagger 之后,我们可以通过 OpenAPI 规范摘要 了解它的基本语法。

注意

  1. 这里面有个坑,如果想达到这样的效果: image.png 图中红色框的代码其实是不用写的: image.png 否则它会: image.png
  2. 如果在responses时有多个响应状态码,比如 200500 等等,需要给状态码加上引号,才能正确显示: image.png

整体代码

// 登录接口
/**
 * @swagger
 * /user/login:
 *   post:
 *     description: 用户登入
 *     tags: [用户登入模块]
 *     produces:
 *       - application/json
 *     parameters:
 *       - name: account
 *         description: 账号
 *         in: formData
 *         required: true
 *         type: string
 *       - name: email
 *         description: 邮箱账号
 *         in: formData
 *         required: true
 *         type: string
 *       - name: password
 *         description: 密码
 *         in: formData
 *         required: true
 *         type: string
 *       - name: captcha
 *         description: 验证码
 *         in: formData
 *         required: true
 *         type: integer
 *       - name: runtime_captcha
 *         description: 发送验证码的时间戳
 *         in: formData
 *         required: false
 *         type: integer
 *       - name: session
 *         description: sessionID
 *         in: formData
 *         required: false
 *         type: string
 *     responses:
 *       '200':
 *          description: 登录成功的响应
 *          schema:
 *              type: object
 *              required:
 *                - code
 *                - msg
 *                - data
 *              properties:
 *                 code:
 *                     type: integer
 *                     format: int64
 *                     example: 200
 *                 msg:
 *                    type: string
 *                    example: 登录成功
 *                 data:
 *                    type: object
 *                    properties:
 *                        status:
 *                             type: boolean
 *                             example: true
 *       '500':
 *         description: 数据写入失败
 *         schema:
 *              type: object
 *              required:
 *                - code
 *                - msg
 *                - data
 *              properties:
 *                 code:
 *                     type: integer
 *                     format: int64
 *                     example: 500
 *                 msg:
 *                    type: string
 *                    example: 数据写入失败
 *                 data:
 *                    type: object
 *                    properties:
 *                        status:
 *                             type: boolean
 *                             example: false
 */

页面效果是这样的:
image.png image.png

  • 如果想达到这样的效果:
    image.png

    • 其实只要按同样的步骤编写接口,确保tags是一致的即可: image.png image.png
  • 我们可以测试下,让两个tags不一致:
    image.png

    • 不难发现:
      image.png

提高编写速度

自定义模板

笔者使用的编辑器 WebStorm ,打开方式为:

  1. 依次点击:File - Settings - Editor - Live Templates
  2. 可以看到右上角有个 + ,点击可以看到 image.png
    • 选项1:新建模板,该模板会保存在已选择的模板组中
    • 选项2:新建模板组,该模板组会和其他模板组同级,如 user 就是笔者新建的模板组,然后再在新建的 user 模板组中创建新模板: image.png image.png
  3. 在组件支持的语言文件中输入组件名称,就会看到快捷代码提示,按下 Tab 键就能生成模板内容了:
    image.png

部署至服务器

当我们编写好 API 文档后,我们还需要将其部署到服务器上,以便其他人查阅,否则每次查看接口需要先将后端服务跑起来的话,那无疑是不合理的行为,所以我们还要部署至服务器上。

  1. 根据这两个官网的说明做好相关配置:
  1. 刷新后我们会发现页面报了跨域的错,于是笔者采用 nginx 反向代理的方式处理跨域:

    // 笔者的 nginx 安装路径为 /usr/local/nginx ,因此:
    // 使用 Xshell 连接到服务器后执行 vim /usr/local/nginx/conf/nginx.conf ,编辑文件
    // 全局配置,在 nginx.conf 文件中的 http 节点加入跨域信息
    
    http {
        # 跨域配置
        add_header 'Access-Control-Allow-Origin' '$http_origin' ;
        add_header 'Access-Control-Allow-Credentials' 'true' ;
        add_header 'Access-Control-Allow-Methods' 'PUT,POST,GET,DELETE,OPTIONS' ;
        add_header 'Access-Control-Allow-Headers' 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With' ;
    }
    

    配置完成后要重启 nginx ,让改动生效:/usr/local/nginx/sbin/nginx -s reload(路径改为你自己的 nginx 安装路径)。

  2. 解决跨域后,刷新页面,笔者又看到了新的报错: image.png