Skip to content

Maintaining backwards compatability

If you change your structs, you probably want to be able to interact with data generated by previous versions of your structs. This section explains how you can do that.

For the purpose of this section, any field of type std::optional, std::shared_ptr or std::unique_ptr is an optional field. Any other fields are required.

Please refer to the section on optional fields for details.

Rules

The following rules apply:

  • You can add optional fields.
  • You can remove any optional or required fields, if they are no longer needed.
  • You can change the field names of any optional fields.
  • You can change the order of any existing fields.
  • You can not add any required fields.
  • You can not change the field names of any required fields.

API versioning

If you find it difficult to follow the rules as stated above or you cannot guarantee that you will always be able to follow them in the future, you might want to use API versioning.

You can either use rfl::TaggedUnion or externally tagged variants:

struct API_v_1_0 {
  using Tag = rfl::Literal<"v1.0">;
  ...
};

struct API_v_1_1 {
  using Tag = rfl::Literal<"v1.1">;
  ...
};

...

using APIs = rfl::TaggedUnion<"version", API_v_1_0, API_v_1_1, ...>;
struct API_v_1_0 {
  ...
};

struct API_v_1_1 {
  ...
};

...

using APIs = rfl::Variant<rfl::Field<"v1.0", API_v_1_0>, rfl::Field<"v1.1", API_v_1_1>, ...>;