5

How to send message type as object in ProtoBuf - Proto3 Syntax?

I want to transfer object instead of string or number.

Example

{
  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;
}

Here, I am getting error

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

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

--

Workaround

I can convert it to string in server side, and then I can JSON.parse() at client.

But I want to know, if there any better way to do it.

Aravin
  • 6,605
  • 5
  • 42
  • 58

3 Answers3

9

protocol-buffer does not support the object data type!

But you can emulate your data as hierarchically by using protocol buffer message type itself.

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.
}

In the above example, you can see that the Response message now has "keyvalue" field of type obj(which is a custom type you have just built).

Now you will pass Object in a callback from the server instead of primitive type.

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

Let's say if keys are unknown to you but key/value pair data type is same and known to you then, in this case, you can use map<type, type>

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

References:-

Abhishek Singh
  • 1,631
  • 1
  • 17
  • 31
2

Depending on what you're trying to accomplish, you can likely use one of three types.

  1. The bytes type represents an arbitrary string of bytes. You can choose to encode your types in anyway you feel appropriate.
  2. The any type represents an arbitrary protobuf message, allowing the client or server to encode non-predefined messages. This is a string of bytes, with a unique identifier per message type and language implementations will have ways to unpack the message.
  3. You mention using Javascript. You could likely define a Javascript object message using a combination of oneof for the basic types and map for object types.
csteegz
  • 380
  • 1
  • 5
2

If all of the keys and values you want to send have the same type, you can use a map type. Your example shows string keys and string values, so that could use the type map<string, string>.

If you want to send arbitrary object data with similar structure to JSON objects, you can use the google.protobuf.Struct message type.

murgatroid99
  • 19,007
  • 10
  • 60
  • 95