通过docsify实现接口文档
0、说在前面:
之前使用了apidoc技术生成的接口文档,但是总有多种不便,如:
- 框架束缚太严重,改动源码成本太高。
- 文档的模板较为固定,难以对文档做自定义的保存。
- 由于数据的规范问题,对个别接口字段的数据读取有误,难以数据保证100%的准确性。
继而转向使用docsify技术。
理由如下:
| APIDOC | docsify | |
|---|---|---|
| 文档形式 | data.js–>html | Markdown–>html,未来可兼容飞书文档 |
| 新增内容显示 | 固定模板,额外新增字段需要改源码 | 直接修改.md,所见即所得。 |
| 加载速度 | 稍慢:生成的json文件转js文件包 | 很快:生成Markdown之日,就是html完成之时。 |
| 搜索功能 | 支持目录 | 支持目录+正文 |
| 数据兼容性 | 不规范的数据类型,需修改源码匹配规则 | 支持任何类型 |
| 数据准确性 | 有个别数据排序不准确 | 文档支持任何类型 |
| 扩展性 | 无 | 第三方插件多 |
| 版本对比 | versiong控制,对比清晰 | 无法进行对比 |
高德地图api
https://lbs.amap.com/api/webservice/guide/api/search
1、使用docsify生成接口文档
sa-doc
一个基于markdown的接口文档编写工具,这里没有使用原生docsify,采用开源二次开发后的sa-doc,但框架格式和书写语法都是一样的。
1.1、通过freemarker生成模板文件
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 是一个Java类库。
1、增加pom依赖
1
2
3
4
5
<!-- 引入freemarker模板引擎的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2、配置application.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 是否开启thymeleaf缓存,本地为false,生产建议为true
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.allow-request-override=false
spring.freemarker.check-template-location=true
#类型
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
#文件后缀
spring.freemarker.suffix=.ftl
#路径
spring.freemarker.template-loader-path=classpath:/templates/
3、定义模板文件
apidoc_md.ftl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
## ${moduleName} | ${pageName}
<#list tables as table>
---
### ${table.actionName}
**请求类型**: `${table.method}`  **接口类型**: `${table.interfaceType}`  **版本号**: `${table.version}` **协议号**: `${table.protocolNo}`  **责任人**: `${table.owner}`
**接口描述**: `${table.description}`
**请求Url**:`${table.url}`
**请求参数**
| 变量名 | 备注 | 数据类型 | mock数据 | 是否必须 |
| -------- | ---------- | ------ | --------- | -------- |
<#list table.apiParamsList as apiParam>
| ${apiParam.field} | ${apiParam.description} | ${apiParam.type} | ${apiParam.mock} | ${apiParam.must} |
</#list>
**响应数据**
<style>
table th:first-of-type {
width: 60%;
}
table th:nth-of-type(2) {
width: 15%;
}
table th:nth-of-type(3) {
width: 3%;
}
table th:nth-of-type(4) {
width: 20%;
}
table th:nth-of-type(5) {
width: 2%;
}
</style>
| 变量名 | 备注 | 数据类型 | mock数据 | 是否必须 |
| --------------------- | ----------------------------------- | ---------------------- | -------- | -------- |
<#list table.apiSuccessList as apiSuccess>
| ${apiSuccess.field} | ${apiSuccess.description}| ${apiSuccess.type} | ${apiSuccess.mock}| ${apiSuccess.must} |
</#list>
</#list>
4、编写路由ApiDocController.java
重点代码已隐藏,只展示测试类的处理step,其实原理就是按照test.ftl的关键字将值来put到dataMap中,最后通过template.process将dataMap输出到out目录中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@RequestMapping(value = "/shareApiDoc", method = RequestMethod.GET)
public Map<String, Object> shareApiDoc(@RequestParam(value = "actionId") int actionId) {
// step1 创建freeMarker配置实例
Configuration configuration = new Configuration();
Writer out = null;
try {
// step2 获取模版路径
configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
// step3 创建数据模型
Map<String, Object> dataMap = new HashMap<String, Object>();
//assemble apidoc base info
dataMap.put("apiVersion", apiVersion);
dataMap.put("method", requestType);
dataMap.put("url", actionInfo.getRequestUrl());
dataMap.put("title", actionInfo.getName());
dataMap.put("group", page.getName());
dataMap.put("description", actionInfo.getDescription());
//get apiParamsList
List<ApiParam> apiParams = new ArrayList<>();
dataMap.put("apiParamsList", apiParams);
//get apiSuccessList
List<ApiParam> apiSuccess = new ArrayList<>();
dataMap.put("apiSuccessList", apiSuccess);
// step4 加载模版文件
Template template = configuration.getTemplate("test.ftl");
// step5 生成数据 output to apisrc directory
File docFile = new File(fileSrc.getPath() + "/" + actionInfo.getName() + nowTime + ".java");
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
template.process(dataMap, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != out) {
out.flush();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
1.2、将生成的md文件渲染成网页
上面的步骤简单说就是通过模版生成了markdown格式的文件,接下来要把文件中的数据渲染成网页。
- 将生成的markdown文件放在project目录下。
- 将umeapi_doc目录放置到tomcat上。
- 通过127.0.0.1/umeApi-doc/index.html#/project/share631-2122-10528来访问在线文档
后续规划
多接口文档的分享功能
整个项目接口的分享功能