Default versioning strategy – REST APIs
The default strategy is the first thing to consider when versioning an API. What happens when no version is specified? Will the endpoint return an error, the first or the latest version?If the API returns an error, you should implement that versioning strategy from day one so clients know a version is required. In this case, there is no real drawback. On the other hand, putting this strategy in place after the fact will break all clients that do not specify a version number, which might not be the best way to keep your consumers happy.The second way is always to return the first version. This method is an excellent way to preserve backward compatibility. You can add more endpoint versions without breaking your consumers.The opposite way is always to return the latest version. For consumers, this means specifying a version to consume or be up to date or break, and this might not be the best user experience to provide to your consumers. Nonetheless, many have opted for this default strategy.Another way to go is to pick any version as the default baseline for the API (like version 3.2, for example) or even choose a different version per endpoint. Say you default to 3.2, then deploy 4.0. Since the clients must opt-in to access the new API, they won’t break automatically and will have the time to update from 3.2 to 4.0 following their own roadmap. This is a good strategy to default to a well-known and stable API version before moving forward with breaking changes.
No matter what you choose, always think it through by weighing the pros and cons.
Next, we explore ways to define those versions.
Of course, there are multiple ways to think this through. You can leverage URL patterns to define and include the API version, like https://localhost/v2/some-entities. This strategy is easier to query from a browser, making it simple to know the version at a glance, but the endpoint is not pointing to a unique resource anymore (a key principle of REST), as each resource has one endpoint for each version. Nonetheless, this way of versioning an API is used extensively and is one of the most popular, if not the most popular way of doing REST versioning, even if it violates one of its core principles (debatably).The other way is to use HTTP headers. You can use a custom header like api-version or Accept-version, for example, or the standard Accept header. This way allows resources to have unique endpoints (URI) while enabling multiple versions of each entity (multiple versions of each API contract describing the same entity).For example, a client could specify an HTTP header while calling the endpoint like this (custom header):
GET https://localhost/some-entities
Accept-version: v2
Or like the following, by leveraging the Accept header for content negotiation:
GET https://localhost/some-entities
Accept: application/vnd.api.v2+json
Different people are using different values for the Accept headers, for example:
- application/vnd.myapplication.v2+json
- application/vnd.myapplication.entity.v2+json
- application/vnd.myapplication.api+json; version=2
- application/json; version=2
Whether you are using one way or another, you’ll most likely need to version your APIs at some point. Some people are strong advocates of one way or the other, but ultimately, you should decide on a case-by-case basis what best covers your needs and capacities: simplicity, formality, or a mix of both.