With APIs, Change Happens. API Versioning Options to Consider

Guest post by Mohammed Jasim Uddin; IBM Solution Architect, ESB and Integration SME, API Expert

Introduction
Evolving a REST API is inevitable. Planning ahead to ensure that the API can be evolved along with requirement is a necessary step. Handling the changes in API should be versioned when needed. A new version of the API does not need to be created for new additions or the changes that do not break the existing API consumer code. If there are changes that risk breaking the API consumer code, those should be introduced in a new version of the API.

After the very first version of API in production, any new version should be announced ahead of the time so that the developers’ community can have an opportunity to test it and give feedback on it before deploying into production. Once deployed in production, the new version should be run concurrently with the older version of the API to provide sufficient time to the developers to migrate their code to use the new version of the API. After that, when appropriate time arrives, the old version should be deprecated.

For the convenience of presenting the API version mechanism, let’s assume an API called “myapi” deployed into “server.api.com” domain. The URL to invoke the API will be as below where <params> is the value of API parameters:

https://server.api.com/myapi/<params>

 

Minimizing API Versioning Possibilities
Additions to the API as well as changes that do not break the existing API consumer code can be handled within one version. If  there are breaking changes, i.e. that risks breaking code that is using the API, these should be introduced in a new version of the API.

In order to minimize the possibilities of API versioning, the following guidelines can be followed as much as possible:

  • Existing data field names and data types in API response string should not be changed –for example, a data field name introduced in version 1 should stay same irrespective of future API versions.
  • In case of a drastic change in API response string, such as an existing data filed is removed or existing simple data element is moved into complex data object (an element which consists of multiple data elements), then a new version API may be needed -maintaining multiple versions of API’s and respective code bases would be a overhead; so it is preferable not to maintain more than two versions.
  • For each release of APIs’ – existing output format should continue to stay consistent. API consumers should not develop their code based on any particular order of fields in the API response; rather they should always use the key/value pairs in API response.

API Versioning Options
There are various options available for versioning an API. Here are the three options:

Option #1: URL Versioning
The most common way of versioning an API is to include the version number in every URL. For example:

Pros: The advantage of this option is that the version is available in the URL, easy for everyone to see and use. This is a cleaner approach – this way, the end user (or developer) doesn’t need to handle HTTP headers, and can simply modify the REST API/call to access different versions of the API as needed. It provides the end user an easy opportunity to test the API and get an idea about the output of the new version of the API before accepting it; thus reduces the possibility to surprise the users.

Cons: Introducing version identifiers in the URL leads to multiple end points of an API. Over time, this becomes a burden to maintain as well as a problem for the API client code. Besides that, the API URL can become longer based on version numbering format.

Option #2: Versioning using Content Negotiation
The versioning of API can be achieved by utilizing the Content Negotiation. Content negotiation is a process followed by HTTP server to inspect the structure of an incoming request to figure out the formats in which the client wishes to receive responses. A server can perform content negotiation by one of the following ways:

  • HTTP header based Content Negotiation
  • Query parameter based Content Negotiation

  A) HTTP header based Content Negotiation
HTTP request headers contain settings such as “Accept” and “Content-Type”. These settings can be used to achieve content negotiation. The value of these settings can be any default media types such as application/json, text/xml, text/html or any custom media type containing default media type along with API version number (example: application/v2.0.3+json, application/v2.0.3+xml where v2.0.3 is the version of the API)

Once a HTTP request reaches the API end point, the server inspects “Accept” or “Content-Type” settings in the HTTP request object and then, based on the value of the settings, the server executes branch of the code that provides response in the format that the client has requested.

Different programming languages have methods for the API consumer to set the “Accept” or “Content-Type” value in the http request header. Below are examples of Ajax requests to consume API:

  • The following Ajax performs a GET call to “myapi” API by specifying that it will accept the JSON output from API version v2.0.3

$.ajax({
url: “https://server.api.com/myapi/<params>”,
type: “GET”,
headers: {Accept: “application/v2.0.3+json”}
});

  • The following Ajax performs a GET call to “myapi” API by specifying that it will accept the JSON output from default version

$.ajax({
url: “https://server.api.com/myapi/<params>”,
type: “GET”,
headers: {Accept: “application/json”}
});

  • The following Ajax performs a POST call to an API called “mypostapi” by specifying that the input is in JSON format to the API version v1.0.0

$.ajax({
url: “https://server.api.com/mypostapi”,
type: “POST”,
headers: {Content-Type: “application/v1.0.0+json”}
});

Pros: The advantage of this option is that it provides a way to use the same end point both for old and new versions of API. This will help the API client code stay simple without worrying about URL of the new version of API.

Cons: By using HTTP header based content negotiation in API versioning, the consumer/user will lose the flexibility to invoke the API directly from browser address bar; request needs to be constructed programmatically to set the content negotiation in the header. So, it makes the API harder to test.

  B) Query parameter based Content Negotiation
Query parameter in the URL can be used in content negotiation to determine the content format that is used to exchange data between servers and clients. Based on the value of the query parameter, the server executes branch of the code that provides response in the format that the client has requested.

The following URL contains a query parameter called “version”. The invocation of this URL sends request to myapi API version 2.0.4

https://server.api.com/myapi/<params>?version=2.0.4

Pros: The advantage of this option is that it provides a way to use the same end point both for old and new versions of API even though the version is available in the URL; so it makes it easy for everyone to see and use including from the browser address bar.

Cons: The API URL can become longer based on version numbering format.

Option #3: Versioning using Custom Header
The versioning through HTTP custom header is somewhat similar to HTTP header based Content Negotiation; but it requires a new custom parameter, say “x-api-version”, be introduced in the request header. Once a HTTP request reaches the API end point, the server parses out the custom parameter from the HTTP request object and then, based on the value of the parameter, the server executes branch of the code that provides response in the format that the client has requested.

Different programming languages have methods for the API consumer to set the custom parameter in the http request header. Below is an example of Ajax requests to consume API using custom header:

$.ajax({
url: “https://server.api.com/myapi/<params>”,
type: “GET”,
headers: { ‘x-api-version': ‘v2.0.5′ }
});

Pros: The advantage of this option is that it provides a way to use the same end point both for old and new versions of API. This will help the API client code stay simple without worrying about URL of the new version of API.

Cons: By this API versioning method, the consumer/user will lose the flexibility to invoke the API directly from browser address bar; a request needs to be constructed programmatically to set custom parameter in the header. So, it makes the API harder to test.

My Recommendation on API Versioning Options
One of the important steps in API versioning is to engage the users’ community closely by communicating about upcoming version of API and listening to their feedback as early as possible before moving to production. The URL versioning approach in versioning the API will provide the end users (or developers) an easy opportunity to test and provide feedback early enough to fix an issue; because this approach does not need to handle HTTP headers, and can simply call the API using browser URL address bar. So, it is better to use URL versioning approach even though multiple end points need to be maintained for extended period of time.

Creating and managing different API versions is easy when using the IBM API Management platform, that is available on-premise or as a cloud service. You can sign-up for a 30-day free trial at ibm.biz/apimsaas

Jasim can be reached at: mjuddin@us.ibm.com or jasimuddin1988@yahoo.com