apidoc 实践和自动化生成

导语

在前后端分离框架中,API 文档频繁交接。如果涉及到第三方接口调用,多方合作场景下,API 和文档变更可能会更快。为了方便维护 API 和交接文档,这里给大家推荐一款文档生成工具 - apidoc。

apidoc 简介

apidoc 是一个基于 nodejs 的 API 文档生成工具,从代码注释中提取特定格式的内容,生成 API 文档。

目前支持的语言有:C#、C/C 、D、Erlang、Go、Groovy、Java、Javascript、Pascal/Delphi、Perl、PHP、Python、Rust、Ruby、Scala 和 Swift。

特点:

  • 跨平台,linux、windows、macOS 等都支持。
  • 支持语言广泛。
  • 支持文档版本管理。
  • 支持多个不同语言的多个项目生成一份文档。
  • 输出模板可自定义。

举个例子

以 Django 为例,在 views 函数中写注释

def myview(request, id):  
"""     
    @api {GET} ci/app/:id/ 获取应用详情  
    @apiVersion 1.0.0  
    @apiDescription 获取应用详情  
    @apiName getAppDetail  
    @apiGroup Application  
    @apiSuccessExample  请求成功  
    HTTP/1.1 200 OK  
    {  
        "result": true,  
        "data": [],  
        "code": 0,  
        "message": u'成功说明'  
    }  
    @apiSuccess {Boolean} result true  
    @apiSuccess {Array} data  数据列表  
    @apiSuccess {Number} code 0  
    @apiSuccess {String} message 说明         
    """  

生成的 API 文档

![][1]

apidoc 支持的关键字

apidoc 通过抽取代码注释,根据关键字语法生成 API 文档。所以,如果想生成理想的 API 文档,一定要遵循 apidoc 的相关关键字语法。下面是一个关键字语法的 list,{ }表示需要替换的变量,[ ]表示可选参数:

  • @api {method} path [title]。 只有使用@api 标注的注释块才会在解析之后生成文档,title 会被解析为导航菜单(@apiGroup) 下的小菜单 method 可以有空格,如{POST GET}
  • @apiGroup name。 分组名称,被解析为导航栏菜单
  • @apiName name。 接口名称,在同一个@apiGroup 下,名称相同的@api 通过@apiVersion 区分,否者后面@api 会覆盖前面定义的@api
  • @apiDescription text。 接口描述,支持 html 语法
  • @apiVersion verison。 接口版本,major.minor.patch 的形式
  • @apiIgnore [hint]。 apidoc 会忽略使用@apiIgnore 标注的接口,hint 为描述
  • @apiSampleRequest url。 接口测试地址以供测试,发送请求时,@api method 必须为 POST/GET 等其中一种
  • @apiDefine name [title] [description]。 定义一个注释块(不包含@api),配合@apiUse 使用可以引入注释块 在@apiDefine 内部不可以使用@apiUse
  • @apiUse name。 引入一个@apiDefine 的注释块
  • @apiParam [(group)] [{type}] [field=defaultValue] [description]。请求参数
  • @apiHeader [(group)] [{type}] [field=defaultValue] [description]。头部参数
  • @apiError [(group)] [{type}] field [description]。响应错误时参数
  • @apiSuccess [(group)] [{type}] field [description]。成功时参数, group 表示参数的分组,type 表示类型(不能有空格),入参可以定义默认值(不能有空格)
  • @apiParamExample [{type}] [title] example。参数请求用例
  • @apiHeaderExample [{type}] [title] example。头部请求用例
  • @apiErrorExample [{type}] [title] example。错误请求用例
  • @apiSuccessExample [{type}] [title] example。成功请求用例 type 表示的是 example 的语言类型, example 内容会被直接解析显示。
  • @apiPermission name。 name 必须独一无二,描述@api 的访问权限,如 admin/anyone

安装配置 apidoc

  • 安装 apidoc

这里默认已经安装了 nodejs,如果没有安装,请自行下载安装。全局安装 apidoc:

npm  install apidoc -g      
  • 配置

配置是可选的,没有配置并不影响文档的生成。只是缺失部分 API 文档信息而已。在工程的根目录下,创建 apidoc.json 文件,配置文档的基本信息:

{  
"name": "项目 API 文档",  
"version": "1.0.0",  
"description": "项目 API 文档-说明",  
"title": "项目 API 文档-title"  
}     
  • 生成文档

在 apidoc.json 所在的目录下,执行命令:

apidoc -i ./  

-i 参数表示输入的目录,默认生成的文档在当前目录下的/doc,也可以通过-o 参数指定。

apidoc 自动生成

每次更新代码注释之后,执行一次apidoc -i ./才能看到 API 文档,比较麻烦。能不能每次修改注释之后,自动生成 API 文档呢?当然可以。

  • 安装 gaze

gaze 是基于 nodejs 的文件监控项目。

npm  install gaze -g  
  • 编写监控代码

apidoc-watch.js

var gaze = require('gaze');  
var exec = require('child_process').exec;  

function Watch(){  
    gaze('./*.*',function(error,watcher){  
this.on('all', function(event, filepath) {  
console.log(filepath   ' was '   event);  
        Geneartion();  
      })  
    });  
}  

function Geneartion(){  
var msg = exec('apidoc -e ./node_modules/')  
    msg.stdout.on('data', function (data) {  
console.log('生成 Api->'   data);  
    });  

    msg.stderr.on('data', function (data) {  
console.log('生成出错->'   data);  
    });  
}  

Geneartion();  
Watch();  
console.log('正在监听......');  
  • 执行监控

只需要更新注释之前,执行一次命令即可。

node apidoc-watch.js  

项目实践建议

1 文档的交接方式

建议将 API 文档生成在前端的 static 目录下,以链接的形式交接,比如: htttp://example.com/static/doc/index.html。

2 后端注释组织方式

以 Django 为例,由于 apidoc 需要的注释量比较大,有两种选择:

  • 一种是将注释直接写在每个 views 函数中,
  • 一种是单独使用一个文件或文件夹来写注释。

django 中建议skinny controller, fat model,views.py 中少些代码,多写注释,第一种方案比较合适。同时,注释和接口实现放在一起,可以降低二次维护学习成本。

3 使用 apiDefine 和 apiUse

由于前后端,常常会约定固定格式的返回。可以将格式固定的部分,使用 apiDefine 定义为一个注释块,在其他地方使用 apiUse 引用。可以有效减少注释量。

定义注释块,注意:一个注释块应该被定义为一个单独的注释:

"""  
@apiDefine success  
@apiSuccessExample  请求成功  
HTTP/1.1 200 OK  
{  
    "result": true,  
    "data": [],  
    "code": 0,  
    "message": u'成功说明'  
}  
@apiSuccess {Boolean} result true  
@apiSuccess {Array} data  数据列表  
@apiSuccess {Number} code 0  
@apiSuccess {String} message 说明    
"""  

"""  
@apiDefine error  
@apiErrorExample  请求失败  
HTTP/1.1 40X  error  
{  
    "result": false,  
    "data": [],  
    "code": -1,  
    "message": u'失败提示'  
}  
@apiError {Boolean} result false  
@apiError {Array} data  空  
@apiError {Number} code  错误码  
@apiError {String} message 提示   
"""      

其他地方引用

def myview(request, id):  
"""     
    @api {GET} ci/app/:id/ 获取应用详情  
    @apiVersion 1.0.0  
    @apiDescription 获取应用详情  
    @apiName getAppDetail  
    @apiGroup Application  
    @apiUse success  
    """  

4 合理使用 apiGroup 分组

apiGroup、apiName 会被拼接到 URL 中,比如:static/doc/index.html#api-apiGroup-apiName。给 apiGroup、apiName 取个容易理解的名字很重要。合理使用 apiGroup,将前端相关的功能聚集在一起,有利于前端理解 API 的用途。

参考

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

陈少文的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码匠的流水账

java9系列(一)安装及jshell使用

官网地址http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-38485...

371
来自专栏我有一个梦想

Win.ini和注册表的读取写入

最近在做打包的工作,应用程序的配置信息可以放在注册表文件中,但是在以前的16位操作系统下,配置信息放在Win.ini文件中。下面介绍一下Win.ini文件的读写...

1889
来自专栏信安之路

通过POC来学习漏洞的原理

本文介绍的是 easyFTPServer 1.7.0.2 ‘Http’ remote Buffer Overflow 的漏洞执行流程,通过已知的 POC 来推断...

1180
来自专栏程序员宝库

linux 常用指令

1.查看目录下有什么文件信息 ls //list查看当前目录下有什么文件 ls -l或ls ll //list -list 通过详...

2878
来自专栏吴伟祥

java HttpsURLConnection 实现https请求

图1 部分JSSE类的关系图   假设自己实现的X509TrustManager类的类名为:MyX509TrustManager,下面的代码片...

653
来自专栏开源优测

AutoLine源码之RobotFramework运行器

在AutoLine中我们自定义实现了RobotFramework的运行器,其路径如下图所示:

1033
来自专栏Spring相关

Spring Boot 日志配置

默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台。在运行应用程序和其他例子时,你应该已经看到很多INFO级别的日志了...

956
来自专栏木子墨的前端日常

nginx反向代理跨域基本配置与常见误区

最近公司前后端分离,前端独立提供页面和静态服务很自然的就想到了用nginx去做静态服务器。同时由于跨域了,就想利用nginx的反向代理去处理一下跨域,但是在解决...

692
来自专栏大内老A

ASP.NET Core应用针对静态文件请求的处理[5]: DefaultFilesMiddleware中间件如何显示默认页面

DefaultFilesMiddleware中间件的目的在于将目标目录下的默认文件作为响应内容。我们知道,如果直接请求的就是这个默认文件,那么前面介绍的Stat...

1795
来自专栏青玉伏案

JavaEE开发之SpringBoot整合MyBatis以及Thymeleaf模板引擎

上篇博客我们聊了《JavaEE开发之SpringBoot工程的创建、运行与配置》,从上篇博客的内容我们不难看出SpringBoot的便捷。本篇博客我们继续在上篇...

1955

扫码关注云+社区