Hi everyone! I would like to show you how The Static Contract pitfall could drive APIs to unexpected issues, and how versioning helps to avoid them. For that purpose I will be using O'Reilly's Microservices Antipatterns and Pitfalls and Microsoft site related to RESTful web API design. References were added at bottom.
But what is a pitfall?
According to Richards (2016) a pitfall is
something that was never a good idea, even from the start.
And that is the case for The Static Contract pitfall. This assumption leads APIs to be not flexible enough for contract changes in front of client applications.
The Static Contract Pitfall
Imagine having a REST API endpoint consumed by three different client applications, but one of them needs an extension of a service published. So, the API provider in order to deploy the new changes, requires to check compatibility with the others consumers. Ups! Something goes wrong, the changes imply modifying a JSON contract, then consumers will be impacted and none of them would adapt to those modifications at the same time.
It happens all the time, contracts between providers and consumers are not static. They change very often by adding new features to microservices. However, there are some strategies to keep those issues away and implement backward compatibility without breaking all clients.
Versioning strategies
Header versioning
This type of versioning allows to manage the API version by adding the version number in a custom HTTP Header. It requires that client applications use this header to specify which service version will be consumed.
Besides, it is important to consider server-side cache in case every request was stored, here using a proxy could help to reduce duplicated cache data.
In the next example is showed the creation of a new order using an api-version specified in the Custom-Header.
POST https://enterprise.domain.com/orders/123
Custom-Header: api-version=1
URI versioning
This technique consist in defining the version of an API in the uniform resource identifier (URI). It makes very clear to know which version will be consumed for client applications.
For instance, choosing a version of a service used to retrieve an order could be done by v1 or any custom standard.
It is relevant to mention that this implementation makes harder to follow HATEOS constraint because all links associated to resources should have defined their correct version number.
GET https://enterprise.domain.com/v1/orders/123
Query string versioning
Regarding to this versioning strategy, the version goes in the query string parameter. In that case, it is recommended to establish a default version number when a client misses sending this parameter. The following example uses ?version=3 as query string.
GET https://enterprise.domain.com/orders/123?version=3
As URI strategy, the previous approach has the same issue related to implementation of HATEOS.
MediaType versioning
Finally, very closed to header versioning practice, MediaType needs to be sent in the Accept Content Type Header. Provider is responsible for handling all possible format responses with their defined versions. For example, deleting an order could be performed if version were specified in Accept header along format response required.
DELETE https://enterprise.domain.com/orders/123
Accept: application/vnd.enterprise.domain.com.v2+json
tl;dr
Versioning strategy | Location | Some Considerations |
---|---|---|
Header | Custom HTTP header | Server-side cache issues |
URI | Properly as part of URI | Very simple and clear which version is used Makes harder to implement HATEOAS |
Query String | Query string param of URI | Should be defined a default version value Makes harder to implement HATEOAS |
Mediatype | Accept Http header | Handle all possible format responses with their defined versions Server-side cache issues |
Conclusion
Microservices have became an extended practice in software architecture, from those implementations have emerged many lesson to learn and for this reason there are several antipatterns and pitfalls to take in consideration. Learning from the experience of the others and having in mind those best practices is crucial to build a strong architecture. Here is important to evaluate the options and choose the best one according to context.
References
Richards, M. (2016). Microservices Antipatterns and Pitfalls. CA: O’Reilly Media.
Microsoft (2021). RESTful web API design. Retrieve from https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design
Top comments (0)