Hacker News new | ask | show | jobs
by zbjornson 3612 days ago
> primitive fields set to default values (0 for numeric fields, empty for string/bytes fields) will be skipped during serialization.

I don't totally understand this. Presumably during deserialization they will be set to defaults and not missing? Otherwise, coupled with the removal of required fields, it seems impossible to actually send a 0-value number or empty string, or to send a proto without a field and not have it set to 0 or "" (have to explicitly null the field?).

1 comments

Within the API, proto3 does not have the concept of field presence. All fields are "present" and default to their type's zero value.

Since the client can handle this, there is no need to explicitly serialize default values.

and how do you send a explicit zero so that the client knows that the field is really set by the server and not the default? or a explicit empty string?
One case where this question is important is when you are updating a record stored by the server. You only want to send fields you are changing because the record might be huge. But then how does the server distinguish between fields you didn't set and fields you want to set back to the default? The solution is to also tell the server which fields you are changing in a separate message.

Example:

    {
      'update_record': {
        # Set foo=bar
        'foo': 'bar'
      },
      'fields_to_update': {
        'foo': true,
        # Set some_int_flag=0 (default)
        'some_int_flag': true
      }
    }
See also "Field Masks in Update Operations" https://developers.google.com/protocol-buffers/docs/referenc...
Thanks for explaining that and for the reference. It seems like a lot of overhead for a protocol that is designed to be cheap...
There are also wrapper well known types that you can fallback to (in wrappers.proto), when you need to distinguish between, say empty string and null.
If the client really needs that information, the server must explicitly include it in a seperate field.