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.
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.)