API design and development is the most crucial task for a backend developer. Even when an API has been developed and is in use, changes in it are inevitable over the use as the knowledge and experience of the developers improve and requirements advance. This could be a challenging problem as the threats involve breaking the existing integration for your clients.
API versioning is one of the most common solutions to this problem, however, most of the time it’s an afterthought during the development process whereas it should be the foremost part when starting to design an API.
In this article, we will be discussing some of the best practices for API versioning for ease of user consumption and flexibility. However, the first question that you might have is when to version your APIs. Let’s discuss this in detail before moving on to API versioning best practices.
APIs need to be versioned when there are chances that any new change may complicate or break the existing system. Breaking changes might include any of these cases:
To understand it better, take the following considerations:
There could be many more such cases, but the crux of the matter is that it is necessary to always version your APIs to ensure that the developers have a clear and concise way to consume your ever-changing and up-to-date APIs.
REST APIs don’t have any specific API versioning guidelines, however, the most common approaches are as follows:
Using the URI versioning technique is the simplest and the most commonly used way to version your APIs. Although, it violates an important principle of REST that says that a URI should refer to a unique resource. It looks something like this:
http://api.example.com/v1
http://apiv1.example.com
Here, v[x] is the API version, where x can be any number. However, the version need not be a number or in the exact format.
Alternatives to this format are including dates, project names, or other meaningful identifiers for the team developing the APIs. These should be flexible, short, and concise enough to change as versions change.
Also, it helps the user to refer to the correct documentation.
The burden of serving different versions of the same resource or content can be handled by the API controller or server, which will be responsible for identifying the version of the resource to send as per the request headers.
This tends to result in a more complex API as the users have to know which headers have to be specified before requesting a resource.
API versioning via custom request headers may look like the below:
Accept: application/vnd.example.v1+json
Accept: application/vnd.example+json;version=1.0
This is good as it can also parse the incoming payload on the fly. However, this method can be tricky as it requires an overhead on the server to parse the version prior to sending a response, which could introduce latency.
API version by using query strings as parameters would look like this:
http://api.example.com/:foo?version=v2
This isn’t considered good practice for API versioning as once again, we are violating the principle that says that query strings should be used only for querying data as their name suggests. If you have some type of version control on your data, it wouldn't be incorrect to add a version in the query string depending on what your API is accountable for.
When in doubt, URI or route versioning is the way to go as it will simplify your development process moving forward and keep your users happy.
A word of advice would be to start small and move gradually, especially if you already have an API. Choose an area, examine the data coming in and out of your API platform, and try to standardise it.
Create a set of schema documents that describe the characteristics that comprise each version and explicitly outline the criteria that may be used to validate that data structure. Then, ensure that this information is easily accessed and shared across API users.
Finally, read through resources like the OpenAPI standards and Schema.org. They offer some excellent structural concepts that can assist you in identifying qualities, structuring rules around your schema, and developing an uniform style for delivering this information.
You can also read this StackOverflow thread for more insights from the community.
That was all for this article, I hope you found it helpful. Do let me know your thoughts on the topic.