You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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编解码器,强制输出所有未填充字段:

  1. 导入依赖包:
import (
    "google.golang.org/grpc/encoding"
    "google.golang.org/grpc/encoding/protojson"
    pbjson "google.golang.org/protobuf/encoding/protojson"
)
  1. 在程序初始化阶段注册自定义编解码器:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:53:17