为 protobuf 消息字段定义自定义 go struct 标签

rhi*_*use 7 go protocol-buffers grpc

我是新手grpc并且一直试图json从网络服务器获取响应。然后存根可以jsonrpc服务器请求。

在我的.proto文件中,我创建了一个消息类型:

message Post {
    int64 number = 1;
    string now = 2;
    string name = 3;
}
Run Code Online (Sandbox Code Playgroud)

但我无法编组该number字段,因为protoc生成pb.go带有number标记的结构文件:

{
        "no": "23",
        "now": "12:06:46",
        "name": "bob"
}
Run Code Online (Sandbox Code Playgroud)

如何强制Message使用消息字段的小写名称以外的标签“转换”?如使用json标签no,即使在字段名称Messagenumber

Zak*_*Zak 12

您可以在 proto 消息定义上设置 proto3 字段选项 json_name

message Post {
    int64 number = 1 [json_name="no"];
    string now = 2;
    string name = 3;
}
Run Code Online (Sandbox Code Playgroud)

链接到文档

  • 我试过这个,编译后的结构字段将有以下标签:`数字字符串`protobuf:"bytes,5,opt,name=no,json=com,proto3" json:"number,omitempty"`` (2认同)
  • .proto 文件中的 json_name 选项与生成的 json 标签无关,而是与官方 protobuf 到 JSON 映射中使用的名称有关:https://developers.google.com/protocol-buffers/ docs/proto3#json,它在 [jsonpb](https://godoc.org/github.com/golang/protobuf/jsonpb) 包中实现。[参考](https://github.com/golang/protobuf/issues/998) (2认同)

小智 7

import "github.com/gogo/protobuf/gogoproto/gogo.proto";

// Result example:
// type Post struct {
//    Number int64 `protobuf:"bytes,1,opt,name=number,json=no1,proto3" json:"no2"`
// }
message Post {
    int64 number = 1 [json_name="no1", (gogoproto.jsontag) = "no2"];
}
Run Code Online (Sandbox Code Playgroud)

,在哪里:

  • no1 - jsonpb marshal/unmarshal 的新名称
  • no2 - json marshal/unmarshal 的新名称

jsonpb 示例:

import (
    "bytes"
    "testing"
    "encoding/json"

    "github.com/golang/protobuf/jsonpb"
    "github.com/stretchr/testify/require"
)

func TestJSON(t *testing.T) {
    msg := &Post{
        Number: 1,
    }

    buf := bytes.NewBuffer(nil)

    require.NoError(t, (&jsonpb.Marshaler{}).Marshal(buf, msg))
    require.Equal(t, `{"no1":1}`, buf.String())

    buf.Truncate(0)

    require.NoError(t, json.NewEncoder(buf).Encode(msg))
    require.Equal(t, `{"no2":1}`, buf.String())
}
Run Code Online (Sandbox Code Playgroud)

有关 protobuf扩展的更多信息