如何在ProtoBuf(gRPC)-Proto3语法中将消息类型添加为对象?

时间:2019-08-23 06:45:24

标签: protocol-buffers grpc proto3 protobuf.js grpc-node

如何在ProtoBuf-Proto3语法中将消息类型作为对象发送?

我想转移对象而不是字符串或数字。

示例

{
  name: 'One',
  date: 'date',
  some: 'some',
...
...
}
syntax = "proto3";

package db;

service Proxy
{
    rpc myFunction(Request) returns (Response);
}

message Request
{
    string name = 1;
}

message Response
{
    object keyvalue = 1;
}

在这里,我遇到了错误

throw Error("no such Type or Enum '" + path + "' in " + this);
        ^

Error: no such Type or Enum 'object' in Type

-

解决方法

我可以在服务器端将其转换为字符串,然后可以在客户端使用JSON.parse()。

但是我想知道,是否还有更好的方法。

3 个答案:

答案 0 :(得分:4)

protocol-buffer不支持对象数据类型!

但是您可以使用协议缓冲区消息类型本身来分层模拟数据。

syntax = "proto3";

package db;

service Proxy
{
    rpc myFunction(Request) returns (Response);
}

message Request
{
    string name = 1;
}

message Response
{
    message obj {
         string key1 = 1;
         string key2 = 2
    }
    obj keyvalue = 1;   // Here you have created your own type obj.
}

在上面的示例中,您可以看到响应消息现在具有类型为 obj (这是自定义类型)的“ 键值”字段类型。)

现在,您将在服务器的回调中传递Object而不是原始类型。

callback(null, { keyvalue: { key1: "value1", key2: "value2" } });

如果您不知道密钥,但是您知道密钥/值对的数据类型是相同的,那么在这种情况下,您可以使用 map<type, type>

message Response
{
   map<string, string> keyvalue = 1;
}
callback(null, { keyvalue: { "key1": "value1", "key5": "value2" } });

参考文献:-

答案 1 :(得分:1)

如果要发送的所有键和值都具有相同的类型,则可以使用映射类型。您的示例显示了字符串键和字符串值,因此可以使用类型map<string, string>

如果要发送结构类似于JSON对象的任意对象数据,则可以使用google.protobuf.Struct消息类型。

答案 2 :(得分:0)

根据要完成的任务,您可以使用以下三种类型之一。

  1. bytes类型表示任意字节的字符串。您可以选择以自己认为合适的方式对类型进行编码。
  2. any类型表示任意protobuf消息,允许客户端或服务器对未预定义的消息进行编码。这是一个字节的字符串,每个消息类型具有唯一的标识符,语言实现将有方法来解压缩消息。
  3. 您提到使用Javascript。您可能使用oneof(对于基本类型)和map(对于对象类型)的组合来定义Javascript对象消息。