为protobuf扩展名指定JSON名称

时间:2016-11-04 17:34:05

标签: go protocol-buffers

我已经在消息中添加了扩展消息,需要将其作为json封送。但是,扩展消息的字段名称为[message.extension_message_name]

我希望它只被命名为extension_message_name,没有大括号和前缀,因为这个扩展消息存在于我们的API的其他地方,而且这个奇怪的名称会增加混乱。

据我所知,负责的代码位于protobuf/jsonpb,其中JSONName设置为fmt.Sprintf("[%s]", desc.Name,并且似乎无法覆盖。

任何人都有解决方法吗?

3 个答案:

答案 0 :(得分:1)

根据language guide

消息字段名称被映射到lowerCamelCase并成为JSON对象键。如果指定了json_name字段选项,则将使用指定的值作为键。

因此,用json_name标记字段即可解决问题,例如:

message TestMessage {
    string myField = 1 [json_name="my_special_field_name"];
}

编组为JSON时,应使myField的名称为my_special_field_name

答案 1 :(得分:0)

您有一些选择,但这是因为它们都不是很好:

  1. 使用不同的json struct标签创建一个新结构,然后使用反射将一个结构覆盖到另一个上。

  2. 使用https://github.com/favadi/protoc-go-inject-tag注入自定义结构标签,但是您可能会发现需要使用一个不同于json的其他标签以避免冲突,然后找到一个允许自定义结构标签的json库

  3. 封送json字节以查找并替换为字符串化文本后,重写json字节。

答案 2 :(得分:-1)

一种选择是使用Go的(double *)包和带标签的结构自己解码/封送json,如下所示:

encoding/json

example on play.golang.org

然后输出:

type Example struct {
    ExtMessageName string `json:"extension_message_name"`
}

msg := Example{ExtMessageName: "This is a test"}

jsonBytes, err := json.Marshal(msg)

if err != nil {
    fmt.Printf("error: %v", err)
    return
}

fmt.Println(string(jsonBytes))