Protobuf 中 any 的妙用
文章目录目录结构首先,我们定义我们需要传输的消息使用 protoc 编译工具,编译 rsp.proto,生成 rsp.pb.go 文件测试使用 any在使用 GRPC 时,常规的操作是将 message 定义好后进行数据传输,但总会遇到某些数据结构进行组合的操作,采用默认的定义 message 方式,造成代码量的激增。为了解决这个问题 protobuf 提供类型 any 解决 GRPC 中泛型..
在使用 GRPC 时,常规的操作是将 message 定义好后进行数据传输,但总会遇到某些数据结构进行组合的操作,采用默认的定义 message 方式,造成代码量的激增。为了解决这个问题 protobuf 提供类型 any 解决 GRPC 中泛型的处理方式
目录结构
.
├── main.go
└── rpc
├── rsp.pb.go
└── rsp.proto
首先,我们定义我们需要传输的消息
path
project_dir/rpc/rsp.proto
采用 proto3 协议
定义 TestAny 用于测试 any 的动态传输
定义 Response 作为 GRPC 通用的消息交互
rsp.proto
内容
syntax = "proto3";
package rpc;
option go_package = ".;rpc";
import "google/protobuf/any.proto";
message TestAny {
uint64 Id = 1;
string Title = 2;
string Content = 3;
}
message Response {
uint32 Code = 1;
string Msg = 2;
google.protobuf.Any data = 3;
}
使用 protoc 编译工具,编译 rsp.proto,生成 rsp.pb.go 文件
path
project_dir/rpc/rsp.pb.go
我们并不需要关注 rsp.pb.go 内部的所有内容
仅需要关注生成的消息体
> protoc --go_out=./ rsp.proto
rsp.pb.go
内容
通过 protoc 工具,生成了两个 struct,及为我们定义在 proto 文件中的 message
type TestAny struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id uint64 `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"`
Title string `protobuf:"bytes,2,opt,name=Title,proto3" json:"Title,omitempty"`
Content string `protobuf:"bytes,3,opt,name=Content,proto3" json:"Content,omitempty"`
}
type Response struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Code uint32 `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
Msg string `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
Data *any.Any `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
}
测试使用 any
下面我们将演示实际场景中的应用
通过ptypes.MarshalAny(marshal)
将我们定义的消息进行编码
通过ptypes.UnmarshalAny(any, unmarshal)
对已经编码的消息进行反编码
main.go
内容
func main() {
marshal := &rpc.TestAny{
Id: 1,
Title: "标题",
Content: "内容",
}
any, err := ptypes.MarshalAny(marshal)
fmt.Println(any, err) // [type.googleapis.com/rpc.TestAny]:{Id:1 Title:"标题" Content:"内容"} <nil>
msg := &rpc.Response{
Code: 0,
Msg: "success",
Data: any,
}
fmt.Println(msg) // Msg:"success" data:{[type.googleapis.com/rpc.TestAny]:{Id:1 Title:"标题" Content:"内容"}}
unmarshal := &rpc.TestAny{}
err = ptypes.UnmarshalAny(msg.Data, unmarshal)
fmt.Println(unmarshal, err) // Id:1 Title:"标题" Content:"内容" <nil>
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)