API文档生成工具设计与实现

我一直倡导项目组的开发应该接口设计先行,定下接口协议后各端就可以并行开发了。但是据我了解,还是有不少团队是服务端人员先把接口的逻辑代码写的差不多再交付给客户端接口文档的。通过这个文档生成工具,服务端人员更加愿意提前先设计好接口了,靠工具生成漂亮的文档提前交付未实现的接口给下游人员,而又没有多少增加工作量,整个开发过程会变得更加愉快。

背景

之前有在IDE端根据API文档生成相关接口的数据模型,这减少了客户端这边的工作量,具体可以看上一篇文章:Model代码插件开发。后面想到如果直接让服务端订好接口的代码规范,那么就可以通过写个工具把API文档,Android和IOS的数据模型代码一并生成了,这样既减少了客户端的工作量,又能减少服务端人员的工作量(不用再去手工维护接口文档)。

我们先来看看最终的效果:点击查看

设计思路

服务端环境

目前服务端的API接口是通过Play1.4版本框架来写的,通过研究服务端的代码结构,不难知道它的路由是通过一个conf/routes配置文件来维护的,它的结构如下:

1
2
3
4
# api
POST /api/admin/auth api.admin.AdminController.auth
GET /api/game/list api.game.GameController.list
GET /api/messageList api.MyController.messageList

#是注释,一条路由从左到右分别是[请求方法,请求接口,具体调用所在类的方法],结构非常清晰。

我们来看一下具体某个接口代码:

1
2
3
4
5
6
7
8
9
10
/**
* @Description 消息列表接口
* @param type 消息类型0是系统消息;1是回复我的;2是点赞我的;
* @param page 页码 从1开始
* @author yedaxia
*/
@ApiResult(name = MessageListResult.class)
public void messageList(@Required int type, @Required int page) {
renderJSON();
}

方法的参数和请求的参数一致,注解是一些验证,如果有,表示该参数是必须要传的。

API描述信息

api是客户端和服务端通信的接口,一般是http或者https作为协议载体,主要包含了请求信息和返回的信息。

请求信息:

  • 基本信息
1
2
3
4
接口作用描述
接口作者: yedaxia
method:POST
url: api.github/updateUserinfo
  • 参数列表
参数名 类型 必需 描述
name String true 用户名
  • 返回结果:
1
2
3
4
5
6
7
8
{
"id": "long //用户id",
"name": "String //用户昵称",
"gender": "int //用户性别(1:男;2:女;0:未知)",
"avatar": "String //用户头像",
"token": "String //用户token",
"isNewUser": "int //是否是新用户"
}

返回结果我们用json数据结构表示,这样在多层的数据结构中可读性更强,而且许多应用也是采用的json格式作为返回结果,我们在相应的字段后加入类型和相关的注释。有了这些信息之后,对于客户端开发人员来说就很清晰了,有问题也可以根据作者找到相关的后端人员。

建立关联关系

  1. 基本信息 可以读取routes的路由信息; 接口描述读取方法上的@Description注释信息,接口作者 读取相关接口方法的@author注释。

  2. 参数列表中的参数可以读取方法中参数,参数名类型很容易就对应上,如果有注解@Required或者其他的就视为必传参数,相关注释读取@param注释,这些都和java的编程习惯保持一致。

  3. 返回结果这个就不好直接知道了,通过协商,决定通过添加一个注解来完成,这可能也是唯一增加了服务端工作的一个地方,前面看到的@ApiResult(name = MessageListResult.class)就是我们定义返回结果了,MessageListResult是个简单的JavaBean对象,里面的每个字段和返回的字段一一对应。生成的结果应该支持数组或者列表,类的组合,继承等;每个字段都有类型和相关的注释信息。

展示形式

一开始是打算通过生成markdown的代码,后面发现从markdown转成html代码的几个java库生成效果不是特别理想,最后还是决定通过html模板来实现。

每个Controller作为一个API集合,放在一个单独的文件中,通过锚点和目录的方式来实现方便的跳转。

实现结果

最终的实现效果可以点击这里进行查看,至此,我们API文档的完整性和规范性完全交给代码本身进行维护,并自动生成了相关客户端的数据模型代码,有效减少了大家的工作量,实施效果非常好。

相关代码和例子已经上传到github了,由于当前只能支持Play框架,如果大家有兴趣可以提相关issue或者自己去研读代码,提交自己的实现,笔者有时间会考虑支持其他框架。

进一步思考

我一直倡导项目组的开发应该接口设计先行,定下接口协议后各端就可以并行开发了。但是据我了解,还是有不少团队是服务端人员先把接口的逻辑代码写的差不多再交付给客户端接口文档的。通过这个文档生成工具,服务端人员更加愿意提前先设计好接口了,靠工具生成漂亮的文档提前交付未实现的接口给下游人员,而又没有多少增加工作量,整个开发过程会变得更加愉快。虽然整个流程看起来已经比较顺畅了,但是在应付接口变化还需要进一步的努力,除了接口设计上的扩展性应该更好一些之外,在文档工具上后续会考虑加入ChangeLog。

参考资料

  1. Java反射获取方法的参数名列表
  2. apidoc 开源项目
坚持原创分享,您的支持将鼓励我继续创作!