头图
本文作者:胡亦萍

业界有非常多优秀的API文档管理方案,大多都是基于IDE插件或maven插件的方式做集成。本文主要介绍云音乐自研的基于代码关系、中心化、自动化的API文档管理方案。

背景

随着微服务的发展,在前后端基于API协作的研发模式下,业界涌现了一批优秀的API文档管理工具,如网易自研的NEI、swagger、yapi、smart-docs等等,这些工具通过围绕API文档构建了一系列的能力,极大提升研发效率。
但随着研发流程的迭代更新,也对API文档管理提出了更高的要求。云音乐使用的NEI处于维护阶段,相关功能已经无法满足最新的研发要求,主要体现在:

  1. 依赖手动更新,比较依赖研发人员,文档信息变更时容易存在通知遗漏,影响下游测试或对接方获取最新信息。
  2. 与研发流程结合度低,NEI是基于项目维护API文档信息,缺少研发流程信息,与研发流程的其他系统存在割裂。
  3. API文档维护与代码分离严重,很多代码不维护API文档注释,信息只维护在NEI,随着时间的流逝信息的不一致也给维护带来了问题。

所以我们希望通过构建一个全新的API文档管理平台,解决当前存在的问题,推进API标准化,同时增强API文档的生命周期管理,与研发流程更紧密结合,进一步促进研发提效。

思路&方案

思路

API文档管理平台首先需要确保API文档准确性,在此基础上降低研发人员的维护成本,所以我们需要解决以下几个关键问题:

  1. 如何解决当前存在的文档与代码分离带来的维护问题?
    业界的API文档管理工具基本上都给出了答案,使用javadoc注释。javadoc作为一个通用的类、方法、成员等注释提取标准,使用javadoc作为不需要额外的代码侵入,有天然的优势,而且市面上的AST工具也都支持javadoc提取;通过javadoc可以非常方便地实现代码即文档,降低维护成本。
  2. 如何及时完成API文档创建和更新,且同时保证等待耗时较小呢?
    云音乐的代码都是使用gitlab进行管理,所以我们可以利用gitlab的webhook进行commit信息的推送,基于推送的变更信息做增量解析,避免全量代码的冗余处理;同时采用源码解析方式,减少编译带来的时间损耗;但这里也存在一个问题,就是依赖研发人员及时push代码。
  3. 增量的commit其实存在信息缺失的情况,如何保证完整的变更信息被有效识别?
    API文档中的关系包含API与数据模型的关系、数据模型与数据模型的关系。如果我们能够有效地管理他们的关系,那在增量解析的时候就可以通过这些关系获取完整的信息,从而进行有效的API文档更新。使用传统的数据库无法高效地维护关系,但图数据库能很好地解决这个问题。当某一节点变更时,通过查询节点间的路径关系可以快速获取完整的受影响范围,从而进行有效的信息更新。

基于上述思考,我们确定了以代码为依据,基于AST解析的API文档管理方案。

整体方案

整体方案

关键流程

关键流程

  1. 新接入的应用(由研发协作平台通知)做全量的代码扫描,后续基于gitlab的推送进行增量代码扫描;全量扫描后生成基线的代码关系。
  2. 基于增量代码分析获取基础的变更信息,再基于代码关系获取完整的变更影响范围;每次变更分析后更新代码关系。。
  3. 基于完整的变更范围解析出完整的接口变更信息,更新API文档。
  4. 对更新的API文档进行变更分析,生成变化的差异表;下游可以通过差异表很容易获取变更的内容。
  5. 基于代码所属应用与需求的关系获取API的干系人并进行通知。

关系管理

关系管理在是本方案中一个非常重要的支撑,如果关系无法有效管理,就无法实现高效准确的API文档更新。最终的关系如下图所示
代码关系

图数据库中管理的关系包含:

  1. API节点与数据模型节点的关系:请求、响应等。
  2. 数据模型节点与数据模型节点关系:字段、关联、继承等。

其中所有的节点都包含分支属性,分支属性在节点中的维护的关系如下:
分支关系

  1. 基线关系:master分支节点之间,如DtoA某个字段为DtoB,则关系为DtoA(master)-[field]->DtoB(master)
  2. 当进行分支开发时:

    • 当在dev分支中DtoB节点变更,则此时的关系为DtoA(master)-[field]->DtoB(master),DtoA(dev)-[field]->DtoB(dev)
    • 如DtoA节点变更,则此时的关系为DtoA(master)-[field]->DtoB(master),DtoA(dev)-[field]->DtoB(master)。
  3. 如果没有master分支,只有开发分支,则此时不存在基线关系,所有的分支都按相同分支名维护

功能展示

API文档详情

接口文档

API文档变更内容

接口变更

API文档变更通知

变更通知

实践的过程遇到的一些问题

  1. 因为采用源码解析,如果API中引用了二方包,会导致API文档信息缺失
    基本二方包的维护也是基于git仓库,所以我们约定采用相同分支名进行全局匹配的策略(存在极少的相同路径的情况使用特殊处理)。
  2. 虽然我们在定API标准的时候希望不要有非标的结构,但在实际的API文档的维护中,不可避免会有定义Map结构的场景。
    针对这种情况,我们通过引入特殊的解析逻辑,如下所示

    @Data
    public class AppDTO {
    /**
    * 应用id
    */
    private Integer id;
    
    /**
    * 测试map,
    *
    * @OxLink key1 描述1 {@link CanvasDTO}
    * @OxLink key2 描述2 {@link AppDTO}
    * @OxLink key3 描述3 {@link ComponentDTO}
    */
    private Map<String, Object> addedMap;
    }

    解析结果

总结

这种代码即文档的中心化API文档管理实践带来了许多好处。首先,开发人员只需要在代码中进行Javadoc的修改,就能自动更新API文档,大大简化了文档维护的工作。其次,这种方案使得大部分场景下的API文档更新可以在30秒内完成,提高了开发效率。最重要的是,开发人员将API信息维护在代码中,保证了文档与实际代码的一致性。

最后

更多岗位,可进入网易招聘官网查看 https://hr.163.com/


云音乐技术团队
3.4k 声望3.4k 粉丝

网易云音乐技术团队