web-dev-qa-db-ja.com

protobufメッセージフィールドのカスタムgostructタグの定義

私はgrpcを初めて使用し、Webサーバーからjson応答をフェッチしようとしています。その後、スタブはjsonサーバーからrpcを要求できます。

.protoファイルで、メッセージタイプを作成しました。

message Post {
    int64 number = 1;
    string now = 2;
    string name = 3;
}

しかし、numberprotocタグ付きのstructpb.goファイルを生成するため、numberフィールドをマーシャリングすることはできません。

{
        "no": "23",
        "now": "12:06:46",
        "name": "bob"
}

メッセージフィールドの小文字の名前以外のタグを使用してMessageを強制的に「変換」するにはどうすればよいですか? jsonのフィールド名がnoであっても、Messageタグnumberを使用するなど。

6
rhillhouse

json_nameを使用して、protoメッセージ定義にproto3フィールドオプションを設定できます。

message Post {
    int64 number = 1 [json_name="no"];
    string now = 2;
    string name = 3;
}

ドキュメントへのリンク

4
Zak
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"];
}

、どこ:

  • no1-jsonpbマーシャル/アンマーシャルの新しい名前
  • no2-jsonマーシャル/アンマーシャルの新しい名前

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

Protobufに関する詳細 extensions

4
Jack