REST与RPC

Overview

有一天午饭后和同事聊天时,开始吐槽起接口问题:

  1. 公司的API网关同时支持GET或POST请求方法
    • 使用GET请求时,需要使用URL编码参数存放在URL中,一些int类型传给后端时变成了string
    • 使用POST请求时,需要使用JSON编码参数存放在Body中,参数类型与传递时一致
  2. 参数目前只支持Integer和String类型,不能使用复杂类型,如数组中的参数需要转换为 param.N 的形式,例如data.0、data.1

调用接口的前端很痛苦,开发接口的后台也痛苦,使用静态语言处理这种参数变化的情况更加恐怖,然后话题引到更底层的一些服务开发,和笔者讨论要不用gRPC代替现在的HTTP+JSON接口。虽然gRPC很美好,但笔者还是拒绝了,因为不想再次重构代码。举一个etcd的例子,从v2切换到v3版本的优点很多,但习惯使用curl的开发人员需要切换到etcdctl工具,而我们没有时间来开发类似工具。

RPC和RESTful在不同应用场景下的对比很多,而关于RESTful的用法的争议更多,因为每隔一段时间都会掀起一轮骂战。在各种论坛和SNS上都可以看到这种闹剧:不同背景的人在阐述自己对于RESTful的应用,然后评价其他人在使用方式上的高低贵贱,直到互相进行人身攻击的地步,实在是一件无聊的事情,最后赢家通常是有大量能自圆其说的理论支撑的人,和豆腐脑咸的好吃还是甜的好吃是一个道理。

我们的认知受限于知识背景,有的人习惯使用GET请求所有处理,有的人会因为这样做而抓狂,最好的办法是把这种无聊的问题推给第三方,例如RPC框架,然后去规范函数命名。

笔者所在的公司属于云计算行业,对外提供的接口如开头所述,虽然用户和前端开发人员使用同一套接口,但公司提供了不同语言的SDK,SDK的用户体验良好,就像使用RPC框架一样,只需要按文档设置参数、调用函数就可以完成接口调用。

内部的接口是另一番景象,C/C++和Node.js的框架投入较多,看上去比较规范,其他语言每个团队内部自行处理。多人协作或者跨团队的情况就很尴尬,经常遇到出错调试一番后发现method选错了、参数或者URL拼写错了。在以前使用thrift或者gRPC时是不会发生这种问题的,因为总是由定义接口的人提供描述文件,使用接口的人通过命令行工具从描述文件生成代码。当时最多吐槽的是接口英文命名不规范,其次是自动生成的源文件码量过大导致编辑器卡死。

如何规范开发来提升协作效率,且要对各种语言友好,能让新手、老油条和强迫症患者都能接受?这个问题没有一个稳妥的答案,但笔者认为RPC是最后的归宿,至少在减少心智负担方面有很大的效果,如果没有使用RPC框架,也可以沿用HTTP构建类似的开发方式,偷懒的的办法可以是:

  1. 统一使用POST作为请求方法,JSON作为编码方式
  2. 在URL中存储 action,例如:https://api.wbuntu.com/api/v1/get_resource_list
  3. 在Body中存储 message,采用固定消息格式,例如响应总是包含:RetCode(响应码)、Message(响应信息)、Data(响应数据)
  4. 在Header中存储服务信息、版本、签名......等等,例如:使用Backend字段区别不同后端,使用Signature存储签名用于验签,使用Token鉴权

gRPC就是一个很好的例子:github.com/grpc/grpc/doc/PROTOCOL-HTTP2

comments powered by Disqus