作者:项伟平。Shopee金融团队架构师,负责Shopee商家侧平台的React Native项目研发的架构设计及前沿技术的探索。
Why《深入 ProtoBuf - 简介》一文介绍了Protobuf是一种有别于JSON 或 XML文本传输的新型二进制数据格式,具有安全性好,传输效率高的特点。 Protobuf文件(简称pb文件)在go语言的微服务中被广泛使用,实际开发的情景中,后端同事会丢给我们一个pb文件,也就是接口定义的参数,让前端同事按照结构体传参。这份pb往往成为前后端沟通的桥梁,所以是非常重要的。 定义一个最简单的结构体,通常如下,message 关键字后跟上消息名称,结构体内部则是字段和其数据类型。 message student { string name = 1; int32 age=2 } 作为前端,你可能会想起js对象或者typescript的类型定义文件。ts类型定义文件在接口联调的过程中能够提高开发效率,有效缩减联调时间,提高代码质量。回想一下,你是不是有抱怨过后端给你的字段,在没有数据的时候,有可能是undefined,null,空数组,空字符串,这些都不算恶劣,还有
interface student { name: string; age: number; } 这时候聪明的同学就会想到,能不能让protobuf直接转换成为typescript的类型定义文件。前端同事在联调的时候直接对请求函数进行类型限制,也可以根据请求返回参数的数据结构mock假数据。这种想法直接形成了有效的工作流程,给页面交互联调提高效率。 How怎么去实现protobuf到typescript的转换,首先受到开源工具geotho/protobuf-to-typescript的启发,但是它的源码非常简单,原理不过是字符串替换,非常容易出现报错的情况。所以我需要一个标准的解释器能够精确将protobuf文件转化为抽象语法树(AST)。这时候,我阅读了@grpc/proto-loader的源码,它依赖于开源库protobuf.js。但是protobuf.js所提供的命令行工具(命令如下)不能满足我们的需求,它的转换结果更多是服务于nodejs,应用于服务端工作。
现在我们的目标很明确,如何将protobuf的内容转换为我们想要的typescript类型文件。首先,引入protobufjs,使用
以上是protobuf.js解析出来的数据类型,因为目标主要是面向前端使用的typescript文件,所以我们主要需要针对 FieldField主要指的就是protobuf中的message,它可以转换为ts里面的interface。其中PB类型和TS类型存在一个转换关系。这里存在一个问题即是int64超出js的number类型,如果强制转换则会丢失精度,默认我们将它转换为string。
Enum枚举是Protobuf类型也是Typescript类型,只需做简单转换即可,但是Protobuf中的Enum有可能存在于message当中,而此时,它并非接口参数实现,需要注意。 Methodrpc服务里面的一个方法即是一个method,一般里面包含两个message,分别是入参和出参。 syntax = 'proto3'; service MyService { rpc MyMethod (MyRequest) returns (MyResponse); } message MyRequest { string path = 1; } message MyResponse { int32 status = 1; } 同样,我们需要把Method转换为typescript中的
类型文件可以应用于你自行封装的 const myMethod: MyMethod = (params) => { return request('/my_method', params) } 通过以上说的这些转换,已经可以满足对请求函数的入参出参的typescript类型限制,有效地提高和后台开发这联调的效率。 What功能实现后,可能有人向我推荐easy-mock。首先,easy-mock暂时没支持protobuf。它更多是一个大而全的系统,功能很齐全,但是同样也带来一些问题----接口维护成本。“mock平台需要谁来维护?”这个问题成为最大的阻碍。接口参数应该是由后端工程师定义,但是他们改了参数往往忘了维护在mock平台上。如果交给前端维护,有时候难免会导致通知不到位,沟通成本上升的情况。因此,我更崇尚于“小而美”的工具。 pb-to-typescript它即可以是运行在nodejs上,也可以跑在浏览器上。更简单的是你可以直接打开页面https://brandonxiang./pb-to-typescript/example,直接将protobuf文件复制进行转换,右方输出的则是类型定义文件。这里可以输出
Mock有同学肯定还是会烦恼于mock的问题。正因为我们是从“小而美”的角度触发,我们只需要mock返回参数即可。 在example页面中同样提供了这个功能,将proto文件整个复制进去,点击需要mock的方法名,mock的结果会根据typescript的类型进行简单的mock处理,基本满足页面UI的编写。以上面栗子为例,mock数据可以直接通过
Conclusionpb-to-typescript解决的问题是接口联调中的一个痛点,就是接口还没好,后端同事只提供你一个proto文件。前端同事可以通过proto的内容转换为ts的类型定义并简单mock返回数据,将UI和交互工作前置,提高工作效率,早点下班。 祝大家新的一年不用加班。 题外话Shopee,又称虾皮,是一家腾讯投资的跨境电商平台。这里鼓励提高效率而非加班,技术氛围好。如果想和我并肩作战一起学习,可以找我内推。邮箱 weiping.xiang@shopee.com,非诚勿扰。 |
|
来自: 西北望msm66g9f > 《编程》