Reputation: 147
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
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