API的设计(3) - 实现方式

protoapi实现的方式

接上文,我们选择了protobuf作为IDL,而在代码生成的工具上,我是选择了使用go实现,因为:

  • go开发的程序可以方便的编译为windows / linux / osx上的可执行程序,并且几乎没有任何依赖,非常方便分发
  • go内置有模板引擎,便于代码生成
  • 相关资源丰富

protoapi的核心仅是protobuf的编译器protoc的插件,而protoc本身的运行命令类似:

protoc --api_out=lang=php:[output_path] [api.proto]

那么,这里是需要开发者分别下载protoc以及protoapi的可执行文件,设置好path路径之后才可以运行。

这对于熟悉protoc的开发者来说并不是问题,但对于不熟悉的童鞋来说,有可能产生困扰。

我们会认为,作为工具的提供者,应该尽可能的让使用者感到方便,故此,我们在实现protoapi时:

  • 选择了将protoc也嵌入其中
  • 使用者只需要下载protoapi,然后运行protoapi init命令
  • 便会自动下载所需的protoc,以及设置好path路径。

让使用者可以仅通过protoapi作为命令入口,做代码生成:

protoapi gen --lang=php --out=[output_path] [api.proto]

嵌套调用

运行protoapi gen命令的时候,protoapi实际上会:

  • 获得protoapi自身所在的路径
  • 生成protoc的命令参数,内部另开子进程调用protoc
  • protoc则又会再开子进程调用新的protoapi
    • 第二个protoapi进程,会检测自身的环境,区分自己是被protoc作为插件调用,又或者是被独立运行

嵌套调用类似:



protoapi进程,会检测自身的环境的代码类似:

// main.go
// when no any parameter and not reading from char device
// treat it as being called by protoc
if len(args) == 1 && err == nil && (stat.Mode()&os.ModeCharDevice) == 0 {
  // 被 protoc 作为插件调用
  // 执行代码生成的逻辑
} else {
  // 从命令行被调用,根据命令参数执行逻辑
    cmd.Execute()
}

语言模板

go本身内置有模板支持,text/template是在go 1.9的时候,甚至对生成的代码模板空行控制做了支持,处女座表示很爽。

这样我们可以让通过模板控制,输出空格、空行的排版都严谨的代码。

在开发调试的阶段,我们会希望使用独立的文件来编辑模板,然后实时生效;但在分发、使用的阶段,我们又会希望将这些模板文件跟主进程打包在一起,而不是分发多个文件。

在go里面,我们可以使用esc,自动的将静态资源打包至进程内,成为代码的一部分;但同时又可以通过环境变量,切换从硬盘读取源文件的模式。

debug_tpl属于protoapi一个undocumented的API。

命令行

cobra提供了一个命令行框架,可以方便的添加命令、设置参数、输出帮助等。

测试

开发过程中,经常可能会需要对模板、代码生成逻辑做修改、重构,需要有足够的测试用例支持,确保代码变动后,生成的代码不变。

在这里,自动测试代码实现起来也容易,只需要在程序开发至一定阶段后,拟定一个或者多个完成的proto文件,然后跑一遍代码生成,将生成的文件保存下来作为范本,以后有代码改动,就比较一下重新生成的代码跟范本是否有差异即可。

可以做成go test,也可以简单的搭配jenkins + 脚本做比较。

最后

protoc本身也有各种语言的代码生成,但它是针对直接使用protobuf做对象序列化的场景,而我们这里,首先是要兼容旧的web项目,使用json作为序列化,直接生成新的代码会便利一些。

但对于合适的场景,protoapi也会尽量采用protoc默认生成的代码,然后对其进行扩展。

下一篇我会继续讲protoapirestful / swagger的对比与关系。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357

推荐阅读更多精彩内容

  • 由于工程项目中拟采用一种简便高效的数据交换格式,百度了一下发现除了采用 xml、JSON 还有 ProtoBuf(...
    黄海佳阅读 48,663评论 1 23
  • 去年有段时间得空,就把谷歌GAE的API权威指南看了一遍,收获颇丰,特别是在自己几乎独立开发了公司的云数据中心之后...
    骑单车的勋爵阅读 20,541评论 0 41
  • 本文转自刘明的分享。原文 简介 什么是 Google Protocol Buffer? 假如您在网上搜索,应该会得...
    那样风采阅读 1,601评论 0 1
  • 好友在朋友圈里看到朋友在健身房发的锻炼的视频。 她给我微信留言:“真羡慕她有钱又有闲,可以到健身房去锻炼身体,身材...
    罗二宝阅读 349评论 1 3
  • 快过圣诞节了,大街上店铺门上,展示窗上,门口,最容易被发现的是圣诞树,圣诞老人,雪橇! 一开始摆放的时候,我也会发...
    夏夜冬日阅读 83评论 0 0