gRPC
是一个远程调用框架,使用Protobuf
做为信息的载体来完成客户端和服务端的数据传输。关于怎么定义Protobuf
消息、搭建gRPC
服务在之前的系列文章中都有提及,今天来说一下在使用gRPC
和Protobuf
的过程中怎么传递动态参数。
首先说明一下,这里所说的动态参数指的是在定义Protobuf
消息时还不能确定其具体内容的复合类型字段,简单的说就是消息里的这个字段我们想传一个类似JSON
对象、Map
字典、结构体等等这样的组合值,但是JSON
里有哪些字段、每个字段值是什么类型或者Map
字典键值的类型我们在定义消息时还无法确定(能确定就可以定义子消息嵌套进来了,不在本文的讨论范围内),把这样的Protobuf
消息字段叫做动态参数。
针对通过Protobuf
传递动态参数的需求,官方文档里并没有给出标准的解决方案,目前我所知道的能够通过bytes
、Map
以及proto.Struct
这三种Protobuf
消息字段的类型实现,每种方式也都有自己的优势和劣处,如果你碰巧知道更好的实现方案,欢迎在评论里留言讨论。
下面我们就来看一下使用这三种消息字段的类型如何实现动态参数的传递。
使用bytes传递JSON对象参数
Protobuf
里的bytes
类型的字段编码成Go
代码后对应的是Go
里的字节切片[]byte
类型。所以我们可以把动态参数的字段类型定义成bytes
类型,这样客户端把JSON
对象传递到服务端后,服务端能直接对动态参数里包含的JSON
对象做解码操作,省去了一次从string
到[]byte
的类型转换。
举个例子来说,在下面的Protobuf
消息定义里info
字段的类型是