Specifying the JSON name for protobuf extension

陌路散爱 提交于 2021-02-07 12:46:36

问题


I've added an extending message to a message and need to marshal it as a json. However the field name for the extension message is [message.extension_message_name].

I would prefer it to be named just extension_message_name, without the braces and prefix, since this extension message exists elsewhere in our API and and having this weird name adds confusion.

As far as I can tell the bit of code responsible is in protobuf/jsonpb, where the JSONName is set with fmt.Sprintf("[%s]", desc.Name and cannot be overwritten it seems.

Anyone have a workaround for this?


回答1:


As per the language guide:

Message field names are mapped to lowerCamelCase and become JSON object keys. If the json_name field option is specified, the specified value will be used as the key instead.

So tagging your field with json_name should do the trick, for example this:

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

Should make myField have the name my_special_field_name when marshalled to JSON.




回答2:


You've got some options but that's because none of them are good:

  1. Create a new struct with different json struct tags and then use reflection to overlay one struct onto the other.

  2. Use https://github.com/favadi/protoc-go-inject-tag to inject custom struct tags, but you'll probably find that you need to use a different tag then json to avoid conflicts and then find a json library that allows for a custom struct tag

  3. Rewrite the json bytes after you marshaled it to find and replace in the stringified text.




回答3:


One option would be to use Go's encoding/json package and a tagged struct to decode/marshal the json yourself, something like this:

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))

example on play.golang.org

which then outputs:

{"extension_message_name":"This is a test"}


来源:https://stackoverflow.com/questions/40428691/specifying-the-json-name-for-protobuf-extension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!