Schema Registry and Evolution

In a decoupled architecture (e.g., Kafka, gRPC), the "contract" between services is the schema. A Schema Registry acts as the single source of truth and the gatekeeper for evolution, ensuring that a producer cannot ship a change that crashes its consumers.

The Compatibility Matrix

When updating a schema, you must select a compatibility mode. This decision dictates whether you update consumers or producers first.

| Mode | Who can read what? | Update Order |

|---|---|---|

| **Backward** | New consumer can read old data. | Consumers first. |

| **Forward** | Old consumer can read new data. | Producers first. |

| **Full** | Both are true. | Any order. |

| **None** | No checks. | Dangerous; requires coordinated downtime. |

Practical Evolution Rules (Avro / Protobuf)

- **Adding Fields:** Safe if they are optional or have a default value.

- **Removing Fields:** Safe only in Backward compatibility if the consumers are updated to stop looking for the field before it disappears.

- **Renaming Fields:** Always a breaking change in Avro (use aliases). Safe in Protobuf if the **Field ID** remains the same.

- **Changing Types:** Generally breaking. (e.g., `int` to `string` is not compatible).

Protobuf Field ID Discipline

Protobuf relies on integer tags, not field names. Renaming `user_name` to `username` is fine; changing tag `1` to tag `2` is a catastrophic failure.

```proto

message User {

// Field 1 was removed in v2.0. DO NOT REUSE THE ID.

reserved 1;

reserved "old_field_name";

string username = 2; // Use ID 2

int32 age = 3;

}

```

The Schema Registry Workflow

1. **Producer** attempts to register `Schema v2`.

2. **Registry** checks `v2` against `v1` using the configured compatibility rule (e.g., BACKWARD).

3. **Registry** rejects the schema if it contains a breaking change (e.g., adding a required field without a default).

4. **Consumer** fetches `v2` from the registry by ID when it encounters a message it doesn't recognize.

Tooling Landscape

- **Confluent Schema Registry:** The standard for Kafka/Avro ecosystems.

- **Apicurio Registry:** Red Hat's open-source alternative; supports Avro, Protobuf, and JSON Schema.

- **Buf:** The modern standard for Protobuf/gRPC management, focusing on "linting" schemas like code.

Breaking Changes in Production

If you MUST make a breaking change:

1. Create a **new topic** or a new versioned endpoint (e.g., `/v2/`).

2. Run a "bridge" service that consumes from the old topic, transforms data, and publishes to the new topic.

3. Gradually migrate consumers to the new topic.

Further Reading

- [ApacheKafkaFundamentals](ApacheKafkaFundamentals) — The primary transport for schematized data.

- [EventDrivenArchitecture](EventDrivenArchitecture) — Using schemas as events.

- [ApiDesignBestPractices](ApiDesignBestPractices) — Versioning strategies for REST and GraphQL.