前文
关于grpc的介绍和初步应用,看这篇:https://blog.csdn.net/weixin_42681866/article/details/121509556
本篇主要写出如何应用复杂的protobuf类型
应用
我们在写json的时候,最常写的格式就是字典嵌套列表,或者列表嵌套字典,对于这两者在grpc里如何实现protobuf转换呢?
比如这样一个格式(示例一):
{"food": {"fruit":"apple", "meat": ["pork", "beaf"], "extra": 0}}
再比如这样一个格式(示例二):
[{"fruit": "apple", "meat": "pork"}, {"fruit": "banana", "meat": "beaf"}]
如上两个格式比较典型,前者是字典嵌套列表,后者是列表嵌套字典。我翻了网上的大多数文章,都没有比较好的说明,而官网更是只有这么一篇:https://developers.google.com/protocol-buffers/docs/pythontutorial
所以你能看到,很多博客都只是翻译了下就拿来用了,示例里面的optional在proto3就自然而然支持,而enum这种枚举类型,大多数我们基本用不上,并且里面连map类型都没有…
回到正题,如何定义一个map的格式,且map内嵌套列表,要定义这样一个格式,基本也是逐步试出来的,主要是没翻到相关的资料,如果有人有的话,欢迎评论区指出。就以示例一为例,定义的proto文件如下(这里只写请求体):
// 定义请求体
message FoodRequest {
map<string, EachFood> food_list= 2;
// 定义food里的结构
message EachFood {
string fruit = 1;
repeated string meat = 2;
int32 extra = 3;
}
}
如何应用?如下在python来定义该请求体:
food_request = FoodRequest()
food_list = food_request.food_list # 拿到代表map的food对象
food_list.setdefault('food') # 这里做了限制,不允许直接通过map[key]=value的形式,需要先设置默认值
food_obj = food_list['food'] # 取到EachFood结构
food_obj.fruit = "apple" # 逐一赋值
food_obj.meat.append("port") # 逐一赋值
food_obj.extra = 0 # 逐一赋值
response = stub.Start(food_request) # 将赋值好的request传入即可
上面要注意的就是,通过setdefault先给map类型的key赋值,通过对应repeated格式的append来实现列表的添加,明白这两点写出示例二也是不难