Search code examples
protocol-buffersproto

Adding a new message with required fields to protobuf v2


Say, I have two versions of proto file:

version 1.0 - initial version
version 2.0 - adds a new message with required fields

Is this a valid change in proto file from compatibility point of view ?

IMHO since v2.0 defines a new message with required fields, it should cause backward in-compatibility since if a message is sent from v2.0 to v1.0, v1.0 will not understand it, it wouldn't know how to decode it. And since it is marked required, v1.0 can't even ignore it.


Solution

  • Adding new required fields to an existing message type is a backwards-incompatible change, because old servers won't ever send that field.

    Adding a whole new message type with required fields is backwards-compatible, because old servers won't be sending that message at all. For example, say we start with:

    message Old {
      required int32 i = 1;
    }
    

    Then we add a new message:

    message Old {
      required int32 i = 1;
      optional New m = 2;
    }
    
    message New {
      required string s = 1;
    }
    

    This is backwards-compatible. When an old program sends a message to a new program, the field m will be absent, which is fine because it is optional. The required field m.s is only required if m itself is present.

    When a new program sends a message to an old program, the field m will be ignored. required does NOT mean that the receiver can't ignore it. required only means that the sender is required to send it.

    Note that I strongly recommend against using required. Proto3 removed required, and Cap'n Proto never had it in the first place, because of the unexpected problems it can cause. Here's an in-depth discussion I wrote.

    (Disclosure: I'm the author of Proto2 and Cap'n Proto.)