Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stopping omission of default values in Protocol Buffers

I have a proto schema defined as below,

message User {
   int64 id = 1;
   bool email_subscribed = 2;
   bool sms_subscribed = 3;
}

Now as per official proto3 documentation, default values are not serialized to save space during wire transmission. But in my case I want to receive whether the client has explicitly set true/false for fields email_subscribed/sms_subscribed (because the values were true before but now the user wants to unsubscribe). Hence, when the client sends false for any of these fields, the generator code serializer just omits these fields.

How do I achieve this and avoid the omission of these fields for the above scenario?

PS: I am using Javascript as my GRPC client and Python and GRPC Server.

like image 665
doto Avatar asked May 02 '18 07:05

doto


2 Answers

Update: this has changed recently with the re-introduction of presence tracking info proto3 via a new meaning of the optional keyword:

message User {
   optional int64 id = 1;
   optional bool email_subscribed = 2;
   optional bool sms_subscribed = 3;
}

With this change (now available in protoc etc), explicit assignment is transmitted even if it is the implicit default value.


You cannot under proto3. Your best bet is probably to define a tri-bool enum with not-specified as the first item with value zero, and some true / false values after that.

This will require the same space as a protobuf bool, but will not be binary compatible - so you cannot simply change the declared member type on existing messages. Well, I guess if you make true === 1, then at least that still works - and for the transition you'd have to anticipate false / not specified being ambiguous until you've flushed any old data.

The other option is to add a bool fooSpecified member for every bool foo, but that takes more space and is error-prone due to being manual.

like image 113
Marc Gravell Avatar answered Sep 28 '22 09:09

Marc Gravell


Another option will be to use wrappers with proto3. They basically wrap your value in a message so on the parent message it can be left null.

This way you can differentiate null / false / true on your bool field with a some extra work.

like image 44
garenyondem Avatar answered Sep 28 '22 10:09

garenyondem