2017-10-26 22 views
1

私はprotobufを使用してゴランに新しいサービスを書いています。私は、以下のリクエストJSONを.protoファイルにモデル化したいと思います。protobuf定義としてJSON配列をモデル化する方法

[ 
    { 
    "var": ["myVariable1","myVariable2"], 
    "key1": 123123, 
    "key2": 1122, 
    "key3": "abcd-0101" 
    }, 
    { 
    "var": ["myVariable1"], 
    "key1": 123124, 
    "key2": 1123, 
    "key3": "abcd-0102" 
    }, 
] 

二つの問題は現在ありません:

  • 各配列要素のキーは、それゆえ私は.protoファイルでメッセージを作成し、それを繰り返して作ることができない、事前に知られていません。私はマップを保つ必要があります
  • 私はキーがない配列だけのjsonをモデル化することはできません。毎回私はこれを行うには、次のエラーが表示されます。要求を復号化できませんでした:JSON:できゴー値にないアンマーシャリング配列

以下は、私の.protoファイルです:

syntax = "proto3"; 

package pb; 

import "google/protobuf/empty.proto"; 
import "google/api/annotations.proto"; 

service Transmitter { 
    rpc GetVariables(GetVariablesRequest) returns (GetVariablesResponse) { 
    option (google.api.http) = { 
       post: "/api/v1/{Service}/getVars" 
       body: "*" 
      }; 
    }; 
} 


message GetVariablesRequest { 
    string Service = 1; 
    repeated GetVarInput in = 2; 
} 

message GetVariablesResponse { 
    string msg = 1; 
} 

message GetVarInput { 
    map<string,string> Input = 2; 
} 

私はバイトで試したの代わりにしていますGetVarInputを繰り返しますが、常に空になります。身体も試しました: "*"と本文: "in"

いくつかのポインタを用意してください。

あなたはこのようなあなたのJSONのためのメッセージを書くことができます
+0

カントあなたは自分のJSONブロブに配列にいくつかのプレースホルダ名を与えますか?例えば'{" data ":[{...}、{...}]}' –

答えて

1

:さらに

message RequestMessage { 
    string var = 0; 
    double key1 = 1; 
    double key2 = 2; 
    string key3 = 3; 
} 

、あなたはサティヤムZodeによって答えはのように思えるRequestMessage

message Request { 
    repeated RequestMessage request = 0; 
} 
0

の配列が含まれ、別のメッセージを作成することができます最も合理的なもの。

元の質問では、JSONのすべての柔軟性と動的性質を維持しようとしています。その場合、protobufに変換しようとすると意味がありません。あなたは、JSONを含む文字列フィールドを持つことができます。

しかし、protobufは、RequestMessageのコンテンツの将来の変更をかなりうまく処理します。したがって、まだフィールドの最終セットを知る必要はありません。 Updating a Message Typeに従うだけで、異なる.protoファイルのバージョン間で互換性を保ちます。

1

もう1つの方法は、.protoファイルにAnyメッセージを使用することです。この場合、必要なすべてのGOタイプで繰り返しマップを作成できます。しかし、このアプローチは、強く型付けされたプログラミング言語を使用する柔軟性を提供するので、少しオーバーヘッドです。ここでは例です:

message Any { 
    string type = 1; 
    bytes value = 2; 
} 

とあなたのGOコード内:

func GetRPCAnyValue(value interface{}) *pb.Any { 
    bValue, type_val, _ := MarshlizeValue(value) 
    return &pb.Any{ 
     Type: type_val, 
     Value: bValue, 
    } 
} 
関連する問題