mzh/blog

如何一下午写3000行?记某云的Golang API SDK生产过程

近日参加了某云的SDK编写比赛,官方给的样例是个Python版,请求直接用**params这样方法构造请求体

暴走漫画-你他妈的在逗我

因为尼玛Golang是静态语言,我们严谨!没有可变参数!还没有默认值!!

所以我苦逼地写了一个多小时类似这样的代码:

func (c *Client) GetHostInstance(id string, option string, count int) {
// bla....
}

每个API一遍遍地重复,真是苦不堪言,啥时候是个头啊,人生苦短啊,早知道还用Python了…… 于是我去睡觉了,嗯 梦中Rob Pike托梦醒来,突然想到,几天前学习的Go reflect库,可以反射出调用的type,这样我只要构造struct,然后遍历一下每一项,不就可以省了很多时间了么? 于是,我开始构造各种struct type GetHostInstance struct{ id string option string count int } 从json库中直接拉了些代码来遍历NumField,顿时感觉自己棒棒的!! 但是,写了三个以后我突然发现API里有些参数是optional的!!!

20130422212028-23861660

幸好,Rob大大已经替我等想好了,那就是struct的TagField,于是我TM也构造了一个自己的解析器

type GetHostInstance struct{
 id string `cloud:"optional"`
 option string 
count int }
// .....解析器部分代码
// .....获取tag tag := typ.Field(i).Tag.Get("cloud")

取出tag值之后,依靠检查struct这项是否为nil来确定是否传不传参数! 终于可变参数这么蛋疼的事情都让我解决了,紧接着,我又写了3个struct,累得不行了……年纪轻轻就体力不支了 但是我决定写完去,因为这么漂亮的解决方案不用来拿个马克杯做奖品怎么行?! 于是又写了3个API,我发现我就是在复制粘贴官方的API文档,于是我祭出我的复制粘帖大法+Vim宏 顿时快了很多,变成5分钟一个API,我看了看文档里……TM的一共50多个接口!! 5*50 = 250 分钟 = 4个多小时 = 我都可以拿来看《黑鹰坠落》+ 5集《GTA 5搞笑视频》了!! 于是我开始无聊地点着官方API文档,我突然发现,官方的API文档是用Sphinx写的,只是套了层自己的css而已 –> 因为我的请求体都只是struct,官方还把请求的类型都已经标注好了,这时耳边响起了:人生苦短,我用Python 的标语 我可以用python写个程序,将官方文档直接转成SDK 代码啊!!! 于是,说干就干!! 找了requests等库,人生顿时快乐了很多有没有~ 大法 壮观地生成,连注释都有( ̄▽ ̄) 哈哈哈

生成器代码:https://gist.github.com/mengzhuo/f1b07decb69eea6e7dab

生成好的SDK:https://github.com/mengzhuo/ucloud-go-sdk