Golang gRPC返回ProtoBuf时,空Map字段缺失如何解决?
问题描述
我定义了如下ProtoBuf响应消息:
message Unit { string name = 1; map<string, int32> category = 2; }
在Golang gRPC服务中返回响应时,当category对应的map为空时,响应里会缺失这个字段。
当前响应示例:
{ "units": [ { "name": "abc", "category": { "3": 1, "6": 1 } }, { "name": "abc" } ] }
需求:即使map为空,也要返回category字段对应的空对象,期望响应示例:
{ "units": [ { "name": "abc", "category": { "3": 1, "6": 1 } }, { "name": "abc", "category": {} } ] }
解决方案
方法一:主动初始化空map
构造Unit实例时,直接为Category字段赋值空map,避免其保持nil状态:
unit := &pb.Unit{ Name: "abc", Category: make(map[string]int32), }
这种方式下,ProtoBuf会将空map视为已设置的字段,JSON序列化时会输出"category": {}。
方法二:全局修改JSON序列化配置
如果不想逐个初始化空map,可以全局调整gRPC的JSON编解码器,强制输出所有未填充字段:
- 导入依赖包:
import ( "google.golang.org/grpc/encoding" "google.golang.org/grpc/encoding/protojson" pbjson "google.golang.org/protobuf/encoding/protojson" )
- 在程序初始化阶段注册自定义编解码器:
func init() { customCodec := &protojson.Codec{ MarshalOptions: pbjson.MarshalOptions{ EmitUnpopulated: true, // 关键配置:输出所有未填充字段 UseProtoNames: true, // 可选:保持Proto定义的字段名,需驼峰式可设为false }, UnmarshalOptions: pbjson.UnmarshalOptions{ DiscardUnknown: true, }, } encoding.RegisterCodec(customCodec) }
该配置会作用于所有gRPC接口的JSON响应,空字符串、空切片、空map等未填充字段都会被序列化输出。
内容的提问来源于stack exchange,提问作者sumitya
相关产品推荐
相关产品推荐

