If you absolutely do need it, then in addition to "name" you can also add a field "hasName". If you feel fancy, you can even do that in a code generator.
You do need it for e.g. database records that are nullable or anywhere else that null/nil is a valid state that differs from zero value. Your alternative approach requires manual work on your part rather than being built in to the bindings, and allows for invalid states as pointed out by another commenter.
That’s an extra field, with no consistency validation, and does not play well with JSON. A field can be either "" or null, and that’s two different cases.
Also the wrappers are known to most protobuf code generators, that can then use language features for better ergonomics. E.g. in Rust all wrappers to allow nullability of values will be turned in Option. Like the StringValue will turn into Option<String>.
As for the need, yes, it is needed. This carries intent, which is a good thing in customer facing APIs. An update endpoint will have all fields optional to distinguish between a field needing to be overridden or not, without the need to re-send the value when it does not need to be changed (à la PUT). Having additional boolean fields gets unwieldy quickly.
I think the other commenter’s point is you can use 2 fields to distinguish between the first field being specified as empty vs absent (or whatever terms you prefer).
E.g.
- type.specified => “”
- type.unspecified => empty
The same technique can be used to disambiguate between 0 and empty.
Worth noting that it’s not quite equivalent due to allowing for a malformed message that includes foo = value and hasFoo = false, opening the door to varied client interpretation.
If you absolutely do need it, then in addition to "name" you can also add a field "hasName". If you feel fancy, you can even do that in a code generator.