# 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:

```cpp
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, ...>;
```

```cpp
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>, ...>;
```

