为什么我们要使用protobuf ?

接口联调中常见的问题

最近写接口,和客户端联调比较多,发现了以下几点问题:

  1. 接口返回 [ ]{ } 的问题
    比如正常返回是一个对象,但是如果是空的话,返回的是空数组,此时客户端让我们改为空对象。
    这其实是php本身如此。

  2. 数值 or 字符串?
    因为php是弱类型的,有时候会返回字符串类型的数值(如: 1 , '1')。此时客户端会让我们传指定的数值类型。

  3. 服务端定好的返回的数据结构,客户端不满足,会让我们调整结构。
    比如某个显示,有三个条件满足才显示,此时客户端希望我们提供一个字段控制其显示如否即可。

  4. 写接口文档
    开发者其实都不愿意写文档,我们写好后,后期改了,可能也会忘记调整文档。

以上就是一些常见的问题了。我发现如果使用 protobuf ,可以解决上述问题。
我们来看下 protobuf 的一些优点吧。

使用 protobuf 的优点

  1. protobuf 是基于二进制传输的,所以他比json更安全。并且同样的数据,因为 protobuf 不需要字段名称。传输量更小,省带宽,性能好。

  2. protobuf 传输数据前,是需要根据我们定好的格式,效验数据类型和数据结构的,所以如果数据类型不对,或者少字段,则在传输到客户端前,就截断了,并告诉后端是什么原因。这样就解决了上面的 1,2问题

  3. protobuf 是可以双方协作定好接口返回结构的,避免了上述的 问题3

  4. 写 protobuf 时,可以顺手把字段的注释加上,省掉了写接口文档的烦恼。

给大家看一个 protobuf 文件的示例

syntax = "proto3";
package proto.club;
/*xx请求*/
message ClubListReq {
    base.ReqCode      cmd        = 1;
    base.ExtReq       ext        = 2;
    uint32            page       = 3; // 页码
    optional string   keyword    = 4; // 搜索关键字,可选
}
/*xx返回*/
message ClubListRsp {
    base.RspCode        cmd       = 1;
    base.ExtRsp         ext       = 2;
    uint32              page      = 3;
    uint32              totalPage = 4;
    repeated   ClubInfo clubList  = 5; // 家族列表 [{}, {}, ...]
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
六月的风
Junwind
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 8

服务端用 PHP 实现么?

5个月前 评论
Junwind (楼主) 5个月前

增加复杂度,json就好了嘛

4个月前 评论
Junwind (楼主) 4个月前
梦想星辰大海

数据库的model转protobuf的对象,这个过程有点费人。

4个月前 评论

不是搞游戏这种没必要

4个月前 评论
Buffett-Cai

感觉你好卑微,现在遇到的还是前后端交互的日常问题,客户端让你改啥就改啥,主要原因是没有事先定义好接口数据格式,还不爱写文档,那用什么传输都会存在这种问题,因为传输只管你的数据,不管你的定义,只不过强类型的序列化帮你事先校验了一遍格式类型而已。开发中应该是后端主导接口的设计,而不是前端指导后端开展工作,当然了如果前端的工作比后端的高很多那就另说。踩过坑的才会知道后端就应该提供一个字段控制客户端的显示,切勿在前端判断一大堆条件,也不要给个状态status=0然后让前端判断状态显示写死的文案,而应该后端加一个status_text之类的翻译好的文案给前端显示。设计接口表面上看很简单,实际细节可多了,线上版本的迭代都得考虑旧版本的兼容,光这一点都够折腾了,不能接口改动之后,旧版客户端全部崩溃,新版客户端才能用。也不能改个文案就让前端发个版本。不写文档注定只能一个人全栈干了哈,前端不可能去看你代码怎么定义的结构体

4个月前 评论
Junwind (楼主) 4个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!