英文:
Specifying the JSON name for protobuf extension
问题
我已经将一个扩展消息添加到消息中,并需要将其转换为JSON。然而,扩展消息的字段名为[message.extension_message_name]
。
我希望它的名称只是extension_message_name
,而不带有大括号和前缀,因为这个扩展消息在我们的API中的其他地方也存在,并且这个奇怪的名称会增加混淆。
据我所知,负责此操作的代码位于protobuf/jsonpb中,其中使用fmt.Sprintf("[%s]", desc.Name)
设置了JSONName,并且似乎无法被覆盖。
有人有解决这个问题的方法吗?
英文:
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: https://github.com/golang/protobuf/blob/master/jsonpb/jsonpb.go#L256 "jsonpb marshaller"
答案1
得分: 12
根据语言指南:
消息字段名称映射为lowerCamelCase,并成为JSON对象的键。如果指定了json_name字段选项,则将使用指定的值作为键。
因此,通过使用json_name
标记字段,可以解决问题,例如:
message TestMessage {
string myField = 1 [json_name="my_special_field_name"];
}
当编组为JSON时,myField
将被命名为my_special_field_name
。
英文:
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
得分: 0
你有几个选项,但这是因为它们都不是很好:
-
创建一个带有不同 JSON 结构标签的新结构体,然后使用反射将一个结构体覆盖到另一个结构体上。
-
使用 https://github.com/favadi/protoc-go-inject-tag 来注入自定义的结构体标签,但你可能会发现需要使用一个不同的标签来避免冲突,然后找一个允许自定义结构体标签的 JSON 库。
-
在将其编组为字符串后,重写 JSON 字节,以查找和替换字符串化的文本中的内容。
英文:
You've got some options but that's because none of them are good:
-
Create a new struct with different json struct tags and then use reflection to overlay one struct onto the other.
-
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
-
Rewrite the json bytes after you marshaled it to find and replace in the stringified text.
答案3
得分: -1
一种选择是使用Go的encoding/json
包和带有标签的结构体来自己解码/编组JSON,类似于以下代码:
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))
运行以上代码将输出:
{"extension_message_name":"This is a test"}
英文:
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))
which then outputs:
{"extension_message_name":"This is a test"}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论