ItsJingran
ItsJingran

Reputation: 147

is it a good way to declare a string field as JSON in gRPC proto?

Since it is quiet trouble some in protobuf to define a flexible structure in some scenario.

for example:

message Foo {
   int a = 1;
   repeated int a_other = 2;
}

In fact, I don't want the service's client to pass the a and the a_other at the same time. However in protobuf, we can't put these two fields in oneof because the a_other is a list field. So with the above message declared, when we only pass the a_other field, the client side cannot tell if the a field is actually 0 or not passed by the server.

So I wonder if define a string field for Foo like:

message Foo {
   string data = 1;
}

and both the server side and the client side is agreed to treat the data field as a JSON. So the server dumps the primitive data and the client loads it, and they live happily ever after.

But my question is, is it a common practice to do that? And what is the disadvantage of it? (this way drop the type check of course) Or is there a better way?

Upvotes: 1

Views: 2878

Answers (1)

Eric Anderson
Eric Anderson

Reputation: 26394

Repeated fields in oneof are generally solved by a wrapper message. In your case:

message Foo {
  oneof choose_one_a {
    int a = 1;
    AOtherMessage a_other = 2;
  }
}

message AOtherMessage {
  repeated int a_other = 1;
}

It seems you can easily stop there.

However, if you do ever find yourself in the "I want arbitrary JSON here" situation, then you would probably want to consider struct.proto's Value instead of a plain string. Value can hold an arbitrary JSON value. If you want to hold an arbitrary JSON object (a.k.a., a map) then use Struct instead. Types in struct.proto are well-known types known to protobuf and when converting a protobuf message to JSON, they are represented in native JSON form.

message Foo {
  google.protobuf.Value a = 1;
}

However, before "dropping the schema and swapping to JSON," you should consult the different ways of handling dynamic content.

Upvotes: 1

Related Questions