在两年前,我提到了怎么去做 API 文档,这在这两年来以来效果不错,问题有,只是都不是很大,因为我们内部都已经形成了习惯。

但是,情况开始变化,尤其是在被 CTO 骂了之后。

目前的流程状况

由于使用的是 apidocjs,我们会在在实现新的接口的时候,在 controllers 里面相应的 handler 上方的注释中写对应的 API 文档,而在动由于历史原因没有文档的老接口时,主动补上文档,然后再进行重构。同时,每次提交代码,都会使用 CI&CD 部署到文档服务器,客户端的同事能够刷新网页及时看到更新的 API 文档,不用费劲下载一个 word 文档,甚至尝试打开的时候可能会格式错误。

整体来说,效率还是不错的,而且也通过自动化的手段提升了效率,那么为何会被骂?

一开始也会觉得很冤,但是,当放下自己的服务端开发的身份,转为从客户端同事的角度去看我们的问题,哎,真叫一个烂。

  • 我们预先假设客户端能看懂 json 的字段类型以及命名含义,于是不会将字段的具体含义解释清楚;
  • 整体风格不统一,很难看;
  • API 文档更新不同步,接口有新字段了,但是接口没有更新,这是由于没有严格对待的结果;
  • 错误情况没有写清楚,导致客户端需要实现很多的防御性代码;
  • 没有版本管理,无法查看接口修改情况(apidocjs 其实是有版本管理的,但是我们没用);

于是,我又在思考,有没有更好的方案?

首先是给不差钱的你

Postman 最近一年动作频频,而且开始收费了,看看它提供的功能,也就能明白该怎么做了。

首先,它最重要的功能,我们一般使用它是为了测试 API 接口,于是它在这个核心功能的基础上,提供了:

  • 文档描述
  • API mock
  • API 接口分组 & 团队成员间同步
  • API 接口分组整体测试
  • 监控

除了最后一个监控有点鸡肋外,前几个功能还是挺实用的,因此,一个好的 API 文档,应该提供

  • 准则无误,与代码实时同步的接口定义
  • 定义代码化,即能放在代码库里面,跟据定义生成文档
  • 支持线上测试
  • 提供 mock 接口

于是,不差钱的你们,可以选择 Postman 来节约精力:想象下,服务端把接口定义写好,加上文档描述后,服务端同事既可以在开发完成之后测试自己的接口,也可以提供 mock 接口给客户端同事,并行开发。

给差钱的你

另外,就是 swagger 了,它目前是最接近我们需求的文档格式,并且连 Postman 也支持它的导入。

于是围绕着 swagger,就有了更好的思路:

我们想要能够『代码即文档』:

  • 根据代码动态生成 swagger 文档;
  • 根据 swagger 文档验证接口的输入与输出;

那么,目前有个验证的工具就入了我们的法眼:joi,它就是可以用来验证输入输出的底层工具,先定义好 schema,然后根据 schema 来验证。

好,再下一步就是如何将接口与这个验证工具结合起来,不妨想想接口的路径是从哪里来的,思路也就有了:API 接口文档的基本结构无非是描述、路径、输入以及输出。显然,一提到这里面最明显路径,你也应该能明白可以从什么地方入手了:路由

于是我们可以在路由上进行一些封装,加一些中间件来验证输入输出,而在我们写路由的时候,必须写上输入输出的验证、接口的描述等等。

那么,我们开发的时候,就会从这样的写法:

1
2
3
4
5
6
7
8
/**
* @api {get} /api Example
* @apiName API name
* @apiGroup api
*
* @apiSuccess {String} a Blablabla.
*/
route.get('/api', handler);

变为这样的写法:

1
2
3
4
route.get({
path: '/api',
desc: 'desc...',
}, validateInput, handler, validateOutput);

最后,将这些描述以及验证提取出来,就可以拼凑成一个能够根据代码实时更新的文档了:这个过程中不用担心文档的字段描述写错,因为文档字段描述错了,代码肯定也会出错,同时这种情况的出现也说明你们单元测试没做好。

总结

其实 koa 已经有现成可以用的了 koa-joi-router-docs,express 的还没用到,你可以看看这个:express-joi-swagger

再仔细一想,我们之所以需要这么做,就是因为 js 是个动态弱类型的语言,它与 API 文档这种强类型的需求完全不搭边,为了桥接它们,我们必须得这么做(从这点来说,我认为 TypeScript 还是很有前景的,有利于项目的长期发展)。

另外,上面说的差钱不差钱也是说笑而已,两个都建议你用的,因为这两个完全可以结合起来,用 swagger 当作文档格式,同时这个文档可以导入 Postman,以及分享给同事,而且 mock 功能还是很不错的,毕竟能够跟客户端并行开发了,能节约不少时间。


首发于 Github issues: https://github.com/xizhibei/blog/issues/85 ,欢迎 Star 以及 Watch

本文采用 署名-非商业性使用-相同方式共享(BY-NC-SA)进行许可
作者:习之北 (@xizhibei)
原链接:https://blog.xizhibei.me/2018/08/26/better-apidoc-process-for-your-team/