How to define an optional field in protobuf 3

前端 未结 9 1377
无人及你
无人及你 2020-12-22 18:14

I need to specify a message with an optional field in protobuf (proto3 syntax). In terms of proto 2 syntax, the message I want to express is something like:

         


        
相关标签:
9条回答
  • 2020-12-22 19:07

    One way is to optional like described in the accepted answer: https://stackoverflow.com/a/62566052/1803821

    Another one is to use wrapper objects. You don't need to write them yourself as google already provides them:

    At the top of your .proto file add this import:

    import "google/protobuf/wrappers.proto";

    Now you can use special wrappers for every simple type:

    DoubleValue
    FloatValue
    Int64Value
    UInt64Value
    Int32Value
    UInt32Value
    BoolValue
    StringValue
    BytesValue
    

    So to answer the original question a usage of such a wrapper could be like this:

    message Foo {
        int32 bar = 1;
        google.protobuf.Int32Value baz = 2;
    }
    

    Now for example in Java I can do stuff like:

    if(foo.hasBaz()) { ... }

    0 讨论(0)
  • 2020-12-22 19:09

    In proto3, all fields are "optional" (in that it is not an error if the sender fails to set them). But, fields are no longer "nullable", in that there's no way to tell the difference between a field being explicitly set to its default value vs. not having been set at all.

    If you need a "null" state (and there is no out-of-range value that you can use for this) then you will instead need to encode this as a separate field. For instance, you could do:

    message Foo {
      bool has_baz = 1;  // always set this to "true" when using baz
      int32 baz = 2;
    }
    

    Alternatively, you could use oneof:

    message Foo {
      oneof baz {
        bool baz_null = 1;  // always set this to "true" when null
        int32 baz_value = 2;
      }
    }
    

    The oneof version is more explicit and more efficient on the wire but requires understanding how oneof values work.

    Finally, another perfectly reasonable option is to stick with proto2. Proto2 is not deprecated, and in fact many projects (including inside Google) very much depend on proto2 features which are removed in proto3, hence they will likely never switch. So, it's safe to keep using it for the foreseeable future.

    0 讨论(0)
  • 2020-12-22 19:12

    There is a good post about this: https://itnext.io/protobuf-and-null-support-1908a15311b6

    The solution depends on your actual use case:

    • Handling partial update

    • Support null

    0 讨论(0)
提交回复
热议问题