protobuf backward compatibility on field name chan

2019-07-16 03:52发布

问题:

If a proto's enum name is changed, is it backward compatible?

e.g I have this initially:

enum ids {
  ID_1 = 1;
  ID_2 = 2; 
};


message {
  ids id = 1
};

And I modify the enum definition to:

enum ids {
  ID_3 = 1;
  ID_2 = 2;
};

Are old proto messages with ID_1 compatible with the new parser compiled from the message that contains ID_3?

回答1:

Since you mentioned using proto3, I have a couple of observations first.

According to the proto3 docs, when defining an enum, you should always declare a zero value as the first entry in the enum value list. This allows protobuf to use 0 as a numeric default value and for compatibility with proto2 semantics where the first enum value is always the default value.

Something like:

enum ids {
  UNKNOWN = 0;
  ID_1 = 1;
  ID_2 = 2; 
};

To your original question, is replacing a label on an existing enum value backward compatible, the answer is yes and no.

It is backward compatible as far as over-the-wire behavior goes. Assume a service has an older version of the proto with ID_1 = 1 and a client has a newer version of the proto with ID_3 = 1. If the server sets ID_1 on its end, this translates to a value of 1 being sent over the wire and will be interpreted as ID_3 on the client end.

It is not backward compatible in the sense that when your revised proto gets compiled into whatever language you are using to handle it, there will be a compile-time break if there was existing code that was consuming the older version of the proto because the label will have changed from ID_1 to ID_3.

Hope this helps.