Skip to main content

Backward Compatibility Rules

OpenAPI

There are a few simple rules, and a couple of exceptions.

  • Requests: do not add mandatories (e.g. adding a new mandatory field, making an optional field mandatory)
  • Responses: do not remove mandatories (e.g. remove a mandatory field, make a mandatory field optional)
  • Do not change value types (e.g. int to string)

Requests

Do not add mandatory keys and / or make values non-nullable for existing keys.

OperationVerdictReason
Add a mandatory keyincompatibleExisting consumers must send a key that they were not sending before.
Add an optional keycompatibleExisting consumers are not sending this key anyway, but new consumers may do so.
Remove a mandatory keycompatibleConsumers can send the key but server will henceforth ignore it.
Remove an optional keycompatibleIf consumers choose to send the key, the server will now ignore it.
Optional key becomes mandatoryincompatibleConsumers who were not sending this key before will now be expected to send it.
Mandatory key becomes optionalcompatibleConsumers who were sending this key before can either continue sending it or stop sending it.

Responses

Do not remove mandatory keys and / or make values nullable for existing keys.

OperationVerdictReason
Add a mandatory keycompatibleOlder consumers were not expecting this key and will ignore it.
Add an optional keycompatibleOlder consumers were not expecting this key and will ignore it. The server may or may not send it, and consumers should be prepared for either.
Remove a mandatory keyincompatibleOlder consumers were expecting this key, but henceforth the response will not contain it.
Remove an optional keycompatibleIn some cases, the server used to send this in the response. Henceforth it never will.
Optional key becomes mandatorycompatibleSometimes the server didn't send this key. But henceforth, the server will always send this key. Consumers who ignored it before can continue doing so. Consumers who checked for it before have code to handle it.
Mandatory key becomes optionalincompatibleIt's possible that the server will not send this key. Some consumers may be expecting it, but will not be receiving it henceforth.

AsyncAPI

For AsyncAPI all of the above rules apply based on this mapping:

  • Requests map to received messages handled by an action: receive type operation.
  • Responses map to messages sent by a reply, x-specmatic-retry, x-specmatic-dlq, or an action: send operation.

In addition, the following rules apply:

OperationVerdictReason
Remove an existing operationincompatibleExisting clients or services still depend on that operation.
Change an operation's actionincompatibleThe interaction changes from receive to send, or vice versa.
Change an operation's channel addressincompatibleExisting producers or consumers will continue using the old topic.
Remove a reply from a request-reply operationincompatibleExisting callers still expect the reply message.
Change the reply channel addressincompatibleExisting callers will continue listening on the old reply topic.
Remove x-specmatic-retryincompatibleExisting retry behavior is broken.
Change the x-specmatic-retry channel addressincompatibleExisting retry consumers will continue using the old retry topic.
Remove x-specmatic-dlqincompatibleExisting dead-letter behavior is broken.
Change the x-specmatic-dlq channel addressincompatibleExisting DLQ consumers will continue using the old DLQ topic.
Change a message correlationId.locationincompatibleExisting correlation logic will read the correlation ID from the old location.
Remove a correlationId from a sent messageincompatibleExisting consumers need it to correlate replies, retries, or DLQ messages.
Add a new operationcompatibleExisting clients and services can ignore it.
Rename an operationcompatibleThe action, topic, reply topic, and message contract are unchanged.
Rename a message reference without changing the resolved message schemacompatibleThe message contract seen on the wire is unchanged.
Rename a correlationId reference without changing its resolved locationcompatibleCorrelation still uses the same message location.
Remove a correlationId from a received messagecompatibleThe receiver no longer requires that correlation ID and will ignore it