API Versioning is critical to ensure that clients are not broken by changes. At the same time, versioning your API with a breaking change requires development work by your consumers.
Developers choosing to version their API MUST evaluate if the breaking changes are worth the business value to the consumer for the time required to make the change.
Be mindful that customers are not interested in "better" versions of the API unless it provides a concrete business value for them to move to.
Individual API routes **MAY **be signaled as unreliable to clients by clearly marking the API documentation with the phrase "ALPHA- " or "BETA - ".
Such routes MUST match the route prefix of /v0.
API routes prefixed by /v0 MAY be changed or removed without warning or notification.
This lets you mark something as "We're working on this" without needing to hide it from your clients. This is useful for getting early feedback from your consumers before the interface is finalized.There is no requirement that APIs support a deprecation cycle for these routes.
API routes not prefixed by /v0 MUST NOT introduce breaking changes.
Breaking changes in the request or response model MUST create a new version of the API. A change is breaking when it is backwards incompatible and results in negative client impact. Backwards incompatible changes include but are not limited to:
- Renaming of a field
- Removal of a field
- Changing the type of a field
Fields MAY be added to APIs without creation of a new version.
Why? Adding fields is already backwards compatible.
Required fields MAY be changed to be no longer required in an API without creation of a new version.
Often, deprecating a field (but not removing it) and working with your clients to stop its use is often an easier conversation than forcing them to a new API version entirely.
Imagine in API that takes:
POST /v1/items
{
"foo": "string",
"qaz": "qux",
"myData": "some:magical,string:2parse",
.....
}
...and you want to change it:
Instead of... | Prefer... |
---|---|
Removing foo | Marking foo deprecated, but continue to populate it. Removing fields may break your clients! |
Renaming foo to bar | Marking foo as deprecated, and adding bar as a new field. Consider populating bar with the contents of foo when *bar *is not set by the client |
Changing *myData *from a string to an object. | Mark myData as deprecated, and create a differently named object. Copy the data from the old field to a value in the new field if appropriate. |
Adding field bar, and making it required, returning a 422 when not provided. | Add bar as optional. If your API truly cannot live without it, first ask why it is now required. If it really is required, you MUST version your API to prevent breaking changes. Your old API must also continue to work. |