protocol-buffersbackwards-compatibility

Oneof field backward compatibility in protobuf


I have a two version of a protobuf message, and wanted to see whether the older version (for clients which are not up to date) is compatible with the newer version.

Old version:

message Foo {
    bool some_boolean_field = 1;
}

Newer version:


message Foo {
    enum SomeEnum {
        A = 0;
        B = 1;
        C = 2;
    }
    oneof oneof_field {
        bool some_boolean_field_in_oneof = 1;
        SomeEnum some_enumeration_field_in_oneof = 2;
    }
}

There's a field in the older version named some_boolean_field, I wanted it to be renamed and also be in a oneof field with another field. Is the newer version compatible with the older version?


Solution

  • Assuming you are using the binary format (rather than the opinionated JSON format), then: yes, you're fine.

    1. in the binary payload format, names don't exist - only field numbers, so: yes, it will make no difference renaming some_boolean_field to some_boolean_field_in_oneof - they're both just field 1 to the format.

    2. oneof doesn't exist in the binary payload format - they're just fields where it just so happens that at most one will be present; there is no additional structural layer introduced by adding a oneof, so adding additional oneof fields, or changing an existing regular field to being a oneof field with the same number and new fields: also fine.

    Changes that are not safe in the binary format include: changing the data type, changing the field number, use of required (in proto2). Changing between a unary and repeated field is not strictly breaking (especially when adding repeated), but may cause confusion.

    If you're using the JSON format, then when renaming a field you might need to use the optional json_name marker in the schema, to preserve the old name in the JSON, so that no data loss occurs.