自研工具的背景介绍
现在主流的web应用开发基本都采用前后端分离的模式,而且大型项目微服务化后,服务间的调用也大多采用http
的连接方式,以rest api
的形式进行调用和返回。因此这些对接方式都离不开API
接口标准,也就是API
接口文档。在这个背景下,这些年业界涌现出很多优秀的API
接口管理工具,针对接口的管理、调试乃至自动化测试方面提供的功能特性,大大提高了软件接口开发和对接的效率。
API
的设计和维护伴随着整个软件开发的生命周期,在逐步的功能迭代和后期的需求变更维护上都或多或少需要对API
接口做一些变更,基于接口、数据模型的复用性或者扩展性的考虑。而在这个过程中,只要遵循API-First
的开发理念,前台和后台应处于同步开发和维护的状态,而实际会涉及一方主动变更的情况,只要受影响的一方及时收到接口变更的通知并捕捉到变更的内容,也能快速调整实现步调一致。因此,API
的版本管理在整个软件开发生命周期中就充当着类似催化剂的作用,保证着软件开发的"活性",减少因接口文档无法协同的消耗。
目前市面上以ApiFox
为代表的管理工具,在API
版本管理方面的功能还有待完善,它们更多是使用文档元数据结合文本对比插件的方式,给用户呈现较为粗糙的对比结果,比如:
因此,为了满足公司老系统向前后端分离模式方向的重构时,能有效提升各方对API
文档接口的共识,高效的推进接口迭代的速度,协调前后端开发的步伐,本人用业余时间研发了一个API
文档生成和对比小工具。 咱们的对比功能更加直观,凡是涉及修改的API
都用浅蓝色背景区分,且内部内容对比的变化都有相应的标色,非常的简洁、大气和直观:
自研工具目前实现了哪些功能
满足oas3(Open API3.1.0)规范
自研工具完全遵循swagger
制定的open api
规范。并在此基础上进行了扩展:
Swagger Codegen二次开发
为了更好满足API
代码生成器生成的接口和数据模型的基本要求和扩展定制功能,对swagger
官方出品的生成器源码进行了二次开发。让生成的代码有更多的特性支持,比如:
再对比下从ApiFox
借助OpenAPI Generator
插件导出的代码,发现接口代码太乱,且无法按对象生成:
另外,ApiFox
没有完全遵循oas3
规范,定义的数据模型都是需要被引用的,字段通过模型进行封装后符合面向对象的设计,字段可以通过模型继承实现重用,比如分页的基础模型,无需重复定义字段。因此,ApiFox
的设计让字段变得更难管理:
用生成的代码快速开发接口
目前,咱们的实现是,直接在项目里集成二开的生成器源码安装后的依赖,代码生成在项目指定的包下,未来我们将结合构建管理工具如gradle
的自定义插件来将生成的代码编译打包发布到maven
制品库,以方便项目引入。目前的结构:
因为生成的接口以及数据模型中对web
表示层该做的各种处理都做了,包括请求映射、json
注解、swagger
文档注解、校验注解等等,开发人员只需要实现controller
,注入service
来完成后台逻辑调用即可。
服务启动后,直接就可以访问到swagger
文档进行相应的调试出结果:
这里的数据校验,早在文档定义时就加上了,开发人员只需要把精力关注在业务逻辑层的实现上即可。
oas文档数据持久化
编写yaml
格式的文档定义,一般只有开发人员自己可以维护,咱们可以把oas
这套定义抽象成非开发人员也可以理解的模型,这样非开发人员也可以通过web
界面来编辑和查看接口文档,做成类似于ApiFox
的接口管理UI
。但是咱们最底层依赖的还是完全遵循oas3
规范的一套文档定义。 为此,研发初期咱们设计了一套数据库表结构用来存储文档中各个部分的定义。同时我们加入了版本管理、历史操作记录的设计,用于版本的对比、历史操作的追溯以及版本还原等特色功能的实现:
因为前期的研发主要精力放在后台功能的实现上,初版数据模型设计出来后,用sql
脚本来初始化文档定义数据,方便运行和调试:
后台核心服务实现
在前面按照yaml
格式的文档定义文件来调用代码生成器功能的基础上,咱们又加了一些核心接口:
主要实现的功能包括了:
- 以本地
yaml
文档定义文件作为入参,调用生成器生成代码 - 以数据库里的文档定义版本为入参,调用生成器,同时导出
yaml
文件并生成代码 - 按照版本号从数据库加载文档定义,用于文档比较或者生成
yaml
文件做后续处理 - 按照版本号从数据库加载文档视图
- 导入
yaml
文档定义文件(暂时只实现到解析并转换成ApiDTO
,数据未入库) - 比较数据库两个版本的文档定义,生成有差异的对比项,供表示层做页面渲染
- 接收两个
ApiDTO
类型的参数进行对比的重载方法,以进一步支持导入的文件与数据库里的版本对比、导入的两个文件之间的对比。 - 待扩展的其他接口。。。
部分功能演示
从数据库加载生成定义文件和代码
待完善的记录id绑定功能
这里从数据库导出的api定义到
yaml
文件中,最好附加上记录的id
,这样方面文档记录的精确对比,如果仅按照name
来对比,只要改了name
那就是两条记录了。
文档视图
可以按照指定的版本或者最新版本查看接口文档视图,关于文档样式方面,目前仅实现了word的简明风格,后期可以采用bootstrap
、foundation
等css框架来美化文档视图:
文档结构说明
文档视图的展现结构分了三层,最外层是请求path
、第二层是请求method
、最内层则是api接口的详情,这样的分层完全符合了rest api
的定义规范,而市面上的一些API工具在接口的结构排布上并没有遵循rest api
规范,没有把path
的维护提取到外层,导致每新增一个接口都要对path
再维护一遍。
文档编辑模式和视图模式对应关系
正常响应的通用返回结构,无需在文档编辑模式每次编辑时人工添加重复的外层结构,用户可以在一处配置下通用结构,在编辑响应内容时直接绑定data
域下的内容即可,生成文档模式时会自动加上通用结构:
同样的数据模型的复用还体现在模型的继承、通用分页模型的维护上等等:
校验的扩展:
分组校验支持:
而过滤分组校验后的暂存接口如下:
字段忽略:
文档对比视图
文档对比可以基于数据库里的任意两个版本,也可以是导入yaml
文件与数据库版本,或者两个导入的yaml
文件的对比。对比的结果将以word文档风格结合对修改部分不同的标色来达到用户体验要求,能一目了然看到文档对比出来的变化的部分。
版本还原功能
为了演示的前面截图的版本间的差异,咱们在数据库里通过增量的记录操作历史记录以及借助我们实现的版本继承的设计来初始化数据:
同时在设计时我们兼顾了用户可能基于一个版本做API
接口文档还原的需求,
咱们的设计上是不允许还原路径产生交叉的,否则版本会乱掉。这里我们要对0.1.1
做的变更还原到0.1.0
,只需要新加一个0.1.2
的版本记录,并设置还原点字段为0.1.0
即可。
页面对比的效果:
再用0.1.2
和0.1.1
对比,0.1.2
版本只是做了还原没有做其他变更,其实比较的就是还原后的0.1.0
和0.1.1
版本,对比的结果正好和上面的截图是相反的:
结束语
后续将在自研工具1.0
版本上继续完善和开发新功能,大家有任何的想法都可以在评论区交流,感谢!