bacar
bacar

Reputation: 10091

Can I retire a required protobuf field?

I have a client-server application where the server transmits serialized objects in protobuf format to a client, and I would like to retire a required field. Unfortunately I can't change both client and server at the same time to use the new .proto definition.

If I change a required field to be optional, but only for code that serializes messages (i.e. deserializing code has not been rebuilt and still thinks it's a required field), can I continue to publish messages that can be deserialized as long as I populate a value for the now-optional field?

(It appears to be fine to do so, at least for a few trivial cases I experimented with (only using Java), but I'm interested if it's a generally sensible approach, and whether there are any edge cases etc I should worry about).

Motivation: My goal is to retire a required field in a client-server application where the server publishes messages that are deserialized by the client. My intended approach is:

  1. Change required field to optional on the trunk.
  2. If it's necessary to deploy new server code (for unrelated features/fixes), ensure that the optional field continues to be populated in the message.
  3. Gradually deploy updated code for all clients (this will take time as it requires involvement of other teams with their own release schedules)
  4. Confirm that all clients have been updated.
  5. Begin to retire (i.e. not populate) the optional field.

Upvotes: 14

Views: 8201

Answers (2)

bacar
bacar

Reputation: 10091

According to the encoding format documentation, whether a field is required or not is not encoded in serialized byte stream itself. That is, optional or required makes no difference in the encoded serialized message.

I've confirmed this in practice, using the Java generated code, by writing serialized messages to disk and comparing the output - using a message containing all of the supported primitive types as well as fields representing other types.

Upvotes: 22

CaTalyst.X
CaTalyst.X

Reputation: 1665

As long as the field is set, using the parseFrom(byte[]) method to deserialize will still work, because the byte[] will be the same.

However, one would wonder why you would change the field from required to optional until you are ready to allow it to be optional? Basically you are just making it "optional" in the .proto file, but you are enforcing that it is required by always populating it. Just a thought.

Upvotes: 3

Related Questions