前言
相信做过开发的,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。其实无论是前端调用后端,还是后端调用后端,都期望有一个好的接口文档。但是这个接口文档对于程序员来说,就跟注释一样,经常会抱怨别人写的代码没有写注释,然而自己写起代码起来,最讨厌的,也是写注释。所以仅仅只通过强制来规范大家是不够的,随着时间推移,版本迭代,接口文档往往很容易就跟不上代码了。
在 gitlab 私有库上写 wiki 文档
早期我们团队的后端接口文档都是写在我们内部的 gitlab 私有库项目中的 wiki 上, 类似于:
但是这样子就会有上面遇到的问题,就是随着接口的迭代,后面的文档的维护也逐渐跟不上。后面就很形式了。
使用 swagger 来生成接口文档并测试
后面使用 swagger 来生成项目的接口文档,并且还支持接口请求测试。
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法、参数和模型紧密集成到服务器端的代码,允许 API 来始终保持同步。Swagger 让部署管理和使用功能强大的 API 从未如此简单。
1. 搭建 swagger ui
因为 swagger ui 是一个静态站点,所以只要本地有 web server 就可以了。首先先到 swagger github git clone 一下最新的版本
虽然这个项目文件很多,但是我们其实只需要 dist 目录下的静态资源文件而已
所以我们将 dist 下面的文件放到 web server 下的 swagger 目录下,这样子就可以直接访问了
这边默认有一个预填的 json1
http://petstore.swagger.io/v2/swagger.json
后面可以在 index.html
修改这个配置, 改成我们自己的项目所生成的 json 文件
而这个 json 文件其实就是 swagger ui 文档配置文件。 他就是通过这个 json 文档来生成接口和测试文档的。 这个 json 格式是这样子的:
这时候替换完成之后,我们就可以看到我们这个项目的文档了:
这时候还不能进行接口测试, 因为这个是本地搭建的,所以直接请求线上的项目,会有跨域问题。 不过如果部署到线上同一个域,或者接口有设置 cors 的话,就可以了。
2. 查看接口并且测试
一旦你的 json 文件有对接口进行文档配置的话,那么就可以在 swagger 上直接查看文档并且还可以进行接口测试。
点击 try it out
按钮就可以进行接口测试
非常的方便。
3. json 文件的生成
我们可以看到 swagger ui 的所有资源都是静态的, 全部是通过加载这个我们所设置的 json 文件来生成接口文档的。 那么这个 json 文件是怎么生成的 ?? 以我们的这个 php 项目为例,找到这个 doc 接口, 可以看到代码很简单1
2
3
4
5
6
7
8
9
10
11
12
13/**
* 生成api doc
* @return Swagger\Annotations\Swagger
*/
public function doc()
{
$swaggerStr = Swagger\scan(base_path('app'));
// header('Content-Type: application/json');
$data = json_decode($swaggerStr, true);
$data['host'] = config('app.doc_host');
// return $swaggerStr;
return $this->echoJson($data);
}
他其实就是调用了一个 swagger 的第三方包
然后根据每一个接口所设置的符合规则的注释 (要符合 swagger 语法),最后生成 json 文档, 所以正常生成的 json 文档是这样子的
当然如果语法有问题的话,就会报错
4. swagger 语法
要为接口生成接口文档,那么就需要在对应的接口写上符合 swagger 语法的注释,以上面截图的 des
加密接口为例,那么他的 swagger 的语法注释就是:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54/**
* @SWG\Definition(
* definition="DesText",
* required={"text"},
* @SWG\Property(
* property="text",
* type="string",
* format="string",
* description="需要加密解密的string"
* ),
* )
*/
/**
* * @SWG\Post(
* path="/utils/des/encrypt",
* tags={"Des"},
* summary="Des Encrypt/ json/text 加密为q串(旧 Q 串)",
* description="返回200即成功",
* @SWG\Parameter(
* name="加密消息串",
* in="body",
* description="raw body为需要加密的串",
* required=true,
* @SWG\Schema(ref="#/definitions/DesText"),
* ),
* consumes={"application/json"},
* produces={
* "application/json"
* },
* @SWG\Response(
* response=200,
* description="成功",
* ),
* @SWG\Response(
* response="500",
* description="加密失败失败",
* @SWG\Schema(ref="#/definitions/Error")
* )
* )
* @param Request $request
* @return mixed
*/
public function encrypt(Request $request)
{
$key = $request->get('key');
if ($key && $key != '' && $key != '{key}') {
$this->rebuildDes($key);
}
$input = file_get_contents('php://input');
//$input = $request->input('text');
return $this->des->encrypt($input);
}
所以只需要在写接口或者迭代接口的时候,补上对应的 swagger 注释,这样子就可以生成对应的接口文档了。 可以说解决了上面的痛点。
关于 swagger 的注释语法, 可以看: Quick Annotation Overview
使用 YApi 来搭建更优雅的文档界面
1. swagger ui 的界面问题
虽然 swagger ui 已经可以很好的处理接口文档和测试,但是当这个项目的接口很多的时候,要查找某一个接口,简直是噩梦,因为他也没有搜索功能, 也没有收藏功能,每次找接口, 全靠 chrome 浏览器的 ctrl + f
的全局搜索。 每次要用几个工具接口的时候,都要找到吐血
而网上针对 swagger ui 的这个界面问题,也是吐槽巨多,而且功能也有点缺陷 (比如测试的时候,不能自定义 header, 没办法写自动化测试脚本), 所以也出现一些很优秀的,并且可以兼容 swagger 的服务, 而我们要用的 YApi 就是其一, 他不仅可以增强测试功能,而且界面更优雅
2. YApi 简介
YApi是高效、易用、功能强大的API管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。YApi在Github上已累计获得了18K+Star,具有优秀的交互体验,YApi不仅提供了常用的接口管理功能,还提供了权限管理、Mock数据、Swagger数据导入等功能,总之功能很强大!
3. 安装
3.1 环境准备
要安装 YApi 需要先安装 nodejs
和 mongoDB
, 所以要先装好。 而 nodejs 和 mongoDB 我的本地环境之前就安装了。 这边就不多做文章
顺便说一下,我的本地环境是 windows 7
3.2 安装 yapi-cli
yapi-cli是YApi官方提供的安装工具,可以通过可视化界面来部署YApi服务,非常方便!
1 | F:\server-readme>npm install -g yapi-cli --registry https://registry.npm.taobao.org |
安装成功后使用yapi server
命令来启动YApi的可视化部署界面。1
2F:\server-readme>yapi server
在浏览器打开 http://0.0.0.0:9090 访问。非本地服务器,请将 0.0.0.0 替换成指定的域名或ip
所以接下来访问 http://127.0.0.1:9090/
来安装 yapi
修改一下路径和其他参数
点击开始部署, 这时候会出现部署日志
后面初始化的时候,报错了, 本地的 mongo的 版本太低了。 至少要 2.6 的版本才行。
1 | Error: error: MongoNetworkError: Server at 127.0.0.1:27017 reports maximum wire version 0, but this version of the Node.js Driver requires at least 2 (MongoDB 2.6), mongodb Authentication failed |
后面我查了一下本地之前安装的 mongo, 发现是 2.4.4, 版本太低了
所以我们得重新装一个更高版本的 mongoDB, 只要是 2.6 以上,因为本地已经有一个旧版本的 mongoDB 了,所以默认端口的 27017 已经被用了, 所以新装的高版本的 mongoDB 就用 27018 的端口来运行
3.3 安装高版本的 mongoDB,并用 27018 端口
通过 https://www.mongodb.com/try/download/community , 我们下载了 4.0.21
的版本。 安装完之后,在安装目录的 bin 目录下的 mongod.cfg
的启动端口改成 27018
同时改完之后,服务还要启动一下 (上面的那个 mongoDB 的服务是旧版本的)
而且这时候的版本就是 4.0.21 了, 终于符合了。
所以接下来继续部署,不过这时候要将部署界面的 数据库端口改成 27018, 这时候就成功了
3.4 启动服务
既然部署成功了,那么接下来就是启动 YApi 服务了1
2
3
4
5F:\my-yapi>node vendors/server/app.js
log: -------------------------------------swaggerSyncUtils constructor-----------------------------------------------
log: 服务已启动,请打开下面链接访问:
http://127.0.0.1:3008/
log: mongodb load success...
这样子服务就启动了,而且 YApi 跟 swagger ui 不一样,他是有用户权限管理的。所以要登录一下。
使用上面的管理员账号 admin@admin.com:ymfe.org 登录一下
4. 使用
4.1 创建项目
接下来我们就要从 swagger 导入数据了, 首先要先建一个分组
然后在该分组下,点击添加项目
创建成功之后,可以看到里面的接口都是空的
4.2 导入项目的 swagger json 文件
接下来我们就要将这个 swagger 项目的接口文档的 json 文件导进去, 点击 数据管理
点击上传, 这时候会弹一个提示
点击确认。 当导出成功之后,至此 我们的某一个项目的 Swagger 中的API接口已成功导入到 YApi,点击接口标签查看所有导入接口。 就可以看到接口列表有我们的接口了
而且整个格局非常的清晰。 点进去接口详情,可以看到具体的信息,包括备注
4.3 设置接口请求 url
接下来试试接口运行功能,我们会发现默认的接口请求地址并不符合我们的要求,需要在环境配置中设置;
我们发现请求地址不是我们想要的, 所以这个得改一下, 所以点击 环境配置
点击环境配置
这样子就好了。
4.4 安装 chrome 跨域插件
因为是本地环境搭建的,然后请求是业务服务接口,所以会有跨域请求 (后面让运维人员将这个 YApi 也放到线上去,就不会有跨域了),Chrome 浏览器需要安装跨域请求插件,下载地址, 这边有 安装文档
所以我们得装一下这个插件 ,不然发送按钮点击不了。
点击下载 zip 包, 解压, 然后到 chrome 的扩展程序那边点击 加载已解压的扩展程序
然后重新刷新一下 YApi 页面,这时候就发现发送按钮可以点击了
然后设置一下参数,最后点击发送,这样子就成功了
4.5 设置 header
而且比之 swagger ui 更好的一点就是,他允许你可以对 header 进行配置。 因为我们有些接口就有安全校验的,而安全校验的token事实上是放到 header 进行请求的。 而不是放到 body 参数体的。
所以我们可以在设置
那边的 环境配置
,对自定义的 header 进行设置。(是不是想到 postman)
点击保存,然后在请求的时候,就可以看到 请求的 header 有带上这个自定义的 header 头部了
这时候就可以看到自定义的 header 就会带过去了。 再测试带有 token header 的接口,特别好用。
5. 从 swagger 自动同步
当我们的接口修改了,API文档如何同步呢,我们可以通过设置
-> Swagger自动同步
来开启自动同步功能,有三种数据同步模式可以选择, 我们选择的是完全覆盖
, 完全将接口定义交给后端
采用默认值就行了,两分钟执行同步一次, 可以看到有 log 输出1
2
3
4log: 定时器触发, syncJsonUrl:https://test-admin.xxx.com/v2/doc,合并模式:merge
log: 定时器触发, syncJsonUrl:https://test-admin.xxx.com/v2/doc,合并模式:merge
log: 定时器触发, syncJsonUrl:https://test-admin.xxx.com/v2/doc,合并模式:merge
log: 定时器触发, syncJsonUrl:https://test-admin.xxx.com/v2/doc,合并模式:merge
6. mock 功能
因为我们的接口定义都全部由后端来处理,所以一般不会用到 mock 功能。但是有时候会遇到接口后端还没有来得及写,但是前端就要联调了,那么就可以用这个 mock 功能,先给前端一个 mock 的接口和返回值。
举个例子,我从公共分类
那边 新建了一个接口,叫 获取自定义用户信息
然后进行编辑, 设置 mock 返回值
最后只要请求 mock 地址 (每一个接口的显示详情下都有一个对应的 mock 地址),就可以了
这样子就非常方便。
7.权限管理
YApi 是有权限管理的,如果有新的成员加入进来,需要查看API文档怎么办? 简单分为三个步骤即可
- 首先可以通过注册界面注册一个成员账号
- 之后使用管理员账号登录,然后通过成员列表->添加成员,将用户添加到相应分组
- 最后使用成员账号登录即可访问相应API文档了。
关于更多的关于 YApi 的权限管理,可以查看 权限权利
总结
通过 Swagger + YApi 的组合,我们可以很好的实现项目的接口文档的编写和测试。 尤其是后者 YApi 的加入,解决了之前只用 Swagger ui 的几个痛点:
- swagger 的界面太难搜索接口, 结合 YApi 可以很快的通过 tag 和 搜索来定位接口, 或者可以创建一个分类来当收藏夹用
- swagger 测试接口的时候,没办法自定义 header 参数, YApi 可以
- YApi 可以设置 mock 返回值,能让前端无需后台实现也可以调试接口
- YApi 可以存放多个项目的接口文档, 而 swagger 要查看其它项目的文档,都得切换 json 链接
- YApi 提供了权限管理功能,可以保证 API 文档的安全
参考文档: