如何将JSON数组建模为protobuf定义

时间:2017-10-26 03:48:05

标签: arrays json go protocol-buffers grpc

我正在使用protobuf在golang中编写一个新服务。我想在.proto文件中建模以下Request JSON。

changecity.ascx

目前有两个问题:

  • 事先不知道每个数组元素中的键,因此我无法在.proto文件中创建消息并重复它。我需要保持地图
  • 我无法建模一个json,它只是一个没有键的数组。每次我这样做,都会显示以下错误:无法解码请求:json:无法将数组解组为Go值

以下是我的.proto文件:

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

我尝试过使用字节而不是重复的GetVarInput,但它总是空的。还试过身体:" *"和身体:"在"

请提供一些指示。

4 个答案:

答案 0 :(得分:1)

你可以像这样为你的json写一条消息:

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

此外,您可以创建另一条包含RequestMessage

数组的消息
message Request {
   repeated RequestMessage request = 0;
}

答案 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,
    }
}

答案 2 :(得分:0)

萨蒂扬·佐德的答案似乎是最合理的答案。

在您的原始问题中,您正在尝试保留JSON的所有灵活性和动态性,并且在这种情况下尝试将其转换为protobuf毫无意义。你可以只有一个包含json的字符串字段。

但是,protobuf确实可以很好地处理RequestMessage内容的未来更改,因此您不必知道最后一组字段。只需按照Updating a Message Type即可在不同的.proto文件版本之间保持兼容。

答案 3 :(得分:0)

service UserService {
  rpc GetUsers(GetUsersRequest) returns (Users) {
    option (google.api.http) = {
      get : "/users"
    };
  };

  rpc GetUser(GetUserRequest) returns (User) {
    option (google.api.http) = {
      get : "/users/{user_id}"
    };
  };
}

message User {
  string id = 1;
  string display_name = 2;
  string icon_image_path = 3;
  string background_image_path = 4;
  string profile = 5;
  string email = 6;
  google.protobuf.Timestamp created_at = 8;
  google.protobuf.Timestamp updated_at = 9;
  google.protobuf.Timestamp deleted_at = 10;
}

message Users {
  repeated User user = 1;
}

message GetUsersRequest {}
message GetUserRequest { string user_id = 1; }