apidoc tool

项目中写文档是常有事情,我们使用的apidoc来写api接口文档。

当使用apidoc里的@apiSuccess参数时,如果接口返回的参数少,比如:

1
2
3
4
5
{
ok: true,
name: 'dillon',
age: 26
}

我们可以很easy的写下:

1
2
3
@apiSuccess Boolean ok
@apiSuccess String name
@apiSuccess Number age

但是当一个接口返回的数据比较多而繁杂,再这样写很浪费时间,且容易出错。

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{
"ok": true,
"layout": [
{
"module": "gameGroup",
"id": "5b45e6292abaf87db8ed28d6",
"title": "街机游戏",
"gameGroup": {
"_id": "5b45e6292abaf87db8ed28d6",
"name": "街机游戏",
"__v": 0,
"games": [
{
"_id": "56e916b2e55db6da66dd8fae",
"name": "射雕英雄传3D",
"cat": "动作冒险",
"intro": "《射雕英雄传3D》是一款金庸正版授权的3D武侠动作手游。游戏改编自\"华人第一武侠作家\"金庸的奠基之作《射雕英雄传》,完美还原了从牛家村到华山论剑的小说剧情,玩家在游戏中不仅能够收集并培养大家耳熟能详的英雄人物,还能与好友一较高下!黄蓉、郭靖、杨康……数十位经典角色悉数登场,将与你展开一段撑霆裂月的江湖之旅。\r\n《射雕英雄传3D》游戏画风精致可爱,使用Unity3D引擎精心打造,完美世界顶级美术亲自操刀游戏原画、场景设计、人物模型。挥毫间再现桃花岛的一川风月、华山之巅的恢弘气势、江南水乡的车水马龙,让玩家犹如置身其间。\r\n追书神器游戏玩家群 117975871>>>>>>>>>>>>>>>>>",
"shortIntro": "金庸正版授权的3D武侠动作手游",
"start": "2016-03-15T16:00:00.000Z",
"iosLink": "",
"iosSize": null,
"androidLink": "https://dn-zhuishu-download.qbox.me/dino.zip",
"androidSize": 419430400,
"androidPackageName": "com.meiqi.sdyxz.android.kaopu",
"icon": "http://statics.zhuishushenqi.com/game-icon/14616570336476?imageView/2/w/144/h/144",
"cover": "http://statics.zhuishushenqi.com/game-cover/146068709521655?imageView/2/w/312/h/156",
"banner": "http://statics.zhuishushenqi.com/game-cover/146068709521521?imageView/2/w/720/h/360",
"__v": 0,
"modified": "2017-05-21T19:00:13.642Z",
"simulatorMainPromo": true,
"h5MainPromo": false,
"mainPromoInfo": {
"desc": "游戏改编自\"华人第一武侠作家\"金庸奠基之作《射雕英雄传》,一较高下吧!",
"playingCount": 31231
},
"mainPromo": false,
"type": "simulator",
"hasGift": false,
"giftFlag": false,
"activityFlag": false,
"hotFlag": false,
"firsthand": false,
"recommend": false,
"sort": 3,
"followers": 1074,
"pasted": false,
"enable": true,
"platforms": [
"android"
],
"pictures": [
"http://statics.zhuishushenqi.com/game-picture/146068709521681?imageView/2/w/1500/h/1500",
"http://statics.zhuishushenqi.com/game-picture/146068709521661?imageView/2/w/1500/h/1500",
"http://statics.zhuishushenqi.com/game-picture/146068709521659?imageView/2/w/1500/h/1500",
"http://statics.zhuishushenqi.com/game-picture/14606870952162?imageView/2/w/1500/h/1500",
"http://statics.zhuishushenqi.com/game-picture/14606870952167?imageView/2/w/1500/h/1500"
]
}
]
}
},
],
"promotions": [{
"_id": "5515313b22a7f74c0371d487",
"name": "小游戏测试1",
"cat": "飞行射击",
"banner": "http://statics.zhuishushenqi.com/game-cover/143997279413641?imageView/2/w/720/h/360",
"type": "simulator"
}]
}

这样一个对象,输出为@apiSuccess的doc的方式不可取,我们肯定想写一个tool来简化每次的操作。

在apidoc文档里,@apiSuccess的用法如下:

1
@apiSuccess {String} firstname Firstname of the User.

里面有返回类型,字段,和字段描述,我们主要关注返回类型和字段。

返回类型大约有如下几种:{Boolean}, {Number}, {String}, {Object}, {String[]}

代码如下:

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
const _ = require('lodash')

let text = ''

getNodes(obj)

console.log(text)

function outputApiDocLine(type, node, pNode) {
type = _.capitalize(type) // 首字母大写
let key = pNode ? `${pNode}.${node}` : `${node}`
return `@apiSuccess {${type}} ${key}\n`
}

function getNodes(target, pNode = '') {
for (let key in target) {
let type = typeof target[key]

if (_.isArray(target[key])) {
let temp = target[key][0]
if (_.isObject(temp)) {
text += outputApiDocLine('object[]', key, pNode)
newPNode = pNode ? `${pNode}.${key}` : key
getNodes(target[key][0], newPNode)
} else {
text += outputApiDocLine('array', key, pNode)
}
} else if (_.isObject(target[key])) {
text += outputApiDocLine(type, key, pNode)
newPNode = pNode ? `${pNode}.${key}` : key
getNodes(target[key], newPNode)
} else {
text += outputApiDocLine(type, key, pNode)
}
}
}

我们这里引用了lodash库来做类型判断和首字母大写。

1
2
3
_.capitalize(str)  // 首字母大写
_.isArray(target) // 是否是数组
_.isObject(target) // 是否是对象

因为数组也是对象的一种,所以先判断数组,再判断对象,然后非对象的直接输出。

采用递归的方式遍历每个子节点,获取对用节点信息。