前言
由于目前公司采用了ProtoBuf做前后端数据交互,进公司以来一直用的是公司大神写好的基础库,完全不了解底层是如何解析的,一旦报错只能求人,作为一只还算有钻研精神的猿,应该去了解一下底层的实现,在这里记录一下学习过程。
Protobuf简单介绍
Google Protocol Buffer(简称 Protobuf)是一种轻便高效的结构化数据存储格式,平台无关、语言无关、可扩展,可用于通讯协议和数据存储等领域。
有几个优点:
- 1.平台无关,语言无关,可扩展;
- 2.提供了友好的动态库,使用简单;
- 3.解析速度快,比对应的XML快约20-100倍;
- 4.序列化数据非常简洁、紧凑,与XML相比,其序列化之后的数据量约为1/3到1/10。
个人感受: 前后端数据传输用json还是protobuf其实对开发来说没啥区别,protobuf最后还是要解析成json才能用。个人觉得比较好的几点是:
- 1.前后端都可以直接在项目中使用protobuf,不用再额外去定义model;
- 2.protobuf可以直接作为前后端数据和接口的文档,大大减少了沟通成本;
没有使用protobuf之前,后端语言定义的接口和字段,前端是不能直接使用的,前后端沟通往往需要维护一份接口文档,如果后端字段有改动,需要去修改文档并通知前端,有时候文档更新不及时或容易遗漏,沟通成本比较大。 使用protobuf后,protobuf文件由后端统一定义,protobuf直接可以作为文档,前端只需将protobuf文件拷贝进前端项目即可。如果后端字段有改动,只需通知前端更新protobuf文件即可,因为后端是直接使用了protobuf文件,因此protobuf文件一般是不会出现遗漏或错误的。长此以往,团队合作效率提升是明显的。
废话了一大堆,下面进入正题。 我这里讲的主要是在vue中的使用,是目前本人所在的公司项目实践,大家可以当做参考。
思路
前端中需要使用 protobuf.js 这个库来处理proto文件。
protobuf.js
提供了几种方式来处理proto。
- 直接解析,如
protobuf.load("awesome.proto", function(err, root) {...})
- 转化为JSON或js后使用,如
protobuf.load("awesome.json", function(err, root) {...})
- 其他
众所周知,vue项目build后生成的dist目录中只有html,css,js,images等资源,并不会有.proto
文件的存在,因此需要用protobuf.js
这个库将*.proto
处理成*.js
或*.json
,然后再利用库提供的方法来解析数据,最后得到数据对象。
PS: 实践发现,转化为js文件会更好用一些,转化后的js文件直接在原型链上定义了一些方法,非常方便。因此后面将会是使用这种方法来解析proto。
预期目标
在项目中封装一个request.js
模块,希望能像下面这样使用,调用api时只需指定请求和响应的model,然后传递请求参数,不需关心底层是如何解析proto的,api返回一个Promise对象:
// /api/student.js 定义接口的文件
import request from '@/lib/request'
// params是object类型的请求参数
// school.PBStudentListReq 是定义好的请求体model
// school.PBStudentListRsp 是定义好的响应model
// getStudentList 是接口名称
export function getStudentList (params) {
const req = request.create('school.PBStudentListReq', params)
return request('getStudentList', req, 'school.PBStudentListRsp')
}
// 在HelloWorld.vue中使用
import { getStudentList } from '@/api/student'
export default {
name: 'HelloWorld',
created () {
},
methods: {
_getStudentList () {
const req = {
limit = 20,
offset = 0
}
getStudentList(req).then((res) => {
console.log(res)
}).catch((res) &