Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to collect all boolean false/true values present in grpc protobuf request in java?

I have a protobuf message which contains boolean fields. When I pass the false value to the boolean fields in the request and when I parse the request the fields containing false values are ignored. For example below:

message Features {
  bool enable_config = 1;
  bool enable_logo_on_screen = 2;
  string custom_url = 3;
  bool enable_footer = 4;
}

message UpdateFeaturesRequest {
  Features features = 1;
}

Assume Features object already present in a database containing the values below:

{
  enableConfig: true,
  enableLogoOnScreen: true,
  customUrl: "https://custom.url.uk/app",
  enableFooter: true
}

Now I want a grpc update request which can update the feature's specific fields so when I fire UpdateFeaturesRequest like below:

{
  enableConfig: false,
  customUrl: "https://custom2.url.hu/app"
}

The output expected is to have an updated features object in DB like:

{
  enableConfig: false,
  enableLogoOnScreen: true,
  customUrl: "https://custom2.url.hu/app",
  enableFooter: true
}

But unfortunately, I am not able to detect the false values in the UpdateFeaturesRequest proto message. I am saving the features object in a JSON format in the Database.

So, when I do: updateFeaturesRequest.getFeatures() then boolean false values are ignored. How can I have the bool false values which are only present in the UpdateFeaturesRequest.

I have got to know that Json formatter ignores boolean false values and we have to do something like:

JsonFormat
   .printer()
   .includingDefaultValueFields()
   .print(message);

But this also includes other default values present in the protobuf message. I want to update only specific fields which are present in UpdateFeaturesRequest. Could someone please help.

like image 514
Deepika Avatar asked Oct 24 '25 04:10

Deepika


1 Answers

In the proto3 version of the language (which you must be using, since I see no optional keywords in your example message), there is no longer any difference between a scalar field that's not present, and a scalar field that has been set to its default value. Quoting from the Default Values chapter of the Language Guide:

Note that for scalar message fields, once a message is parsed there's no way of telling whether a field was explicitly set to the default value (for example whether a boolean was set to false) or just not set at all: you should bear this in mind when defining your message types. For example, don't have a boolean that switches on some behaviour when set to false if you don't want that behaviour to also happen by default.

Consequently, the various language APIs generally do not make this distinction either. If you want to make it possible to know whether enableConfig is false by default, or has explicitly been set to false, you need to redesign the message.

The two most common approaches are probably:

  1. Providing a second bool field that you set to true to denote that the first field's value has been set.
  2. Using the google.protobuf.BoolValue "well-known type", which provides a simple wrapper message for a bool field. For message-typed fields, it's possible to tell the difference between a field that's not been set and a field that's been explicitly set.

You might also consider doing option 2 but with a custom message type, for example FeatureFlag or BooleanFeature, to make it more clear what the meaning is.

(The older proto2 version of the language did make the distinction between "unset" and "set to default", and provided accessors — "hazzers" — that let you query whether a field was explicitly set or not.)

like image 76
fizzie Avatar answered Oct 25 '25 22:10

fizzie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!