Monday, October 13, 2014

REST Resource Versioning





Introduction


Resource versioning is an unavoidable step that should be considered and grasped well and you cannot be sure that you would not need to do versioning in the future throughout the business pipeline. You have to consider versioning from the beginning; if not considered and designed well it may leave your company transfer/maintenance or other related costs. In this paper we will talk about different versioning methods and configurations, practical recommendations and best practices.


Versioning

Resources have to be versioned to prevent conflicts or client-breaks when providing new REST API versions or updates of the same resource; so that old and new clients can continue using and accessing their desired resources or API versions.





Some examples of URI versioning*:



* Note that versioning can also be done using header which will be covered later in this section.


Version identifier can be a number, date-time, a complex string like hash code, can also include alphabetic letters, or etc. Clients may need to upgrade as a new version is introduced. Adding version to URIs or to version hearders depends on your scenario. To version REST resources you would use a versioning method.

Versioning methods specify how you can version REST resources. There are two methods:

1) URI Approach
2) Header Approach




URI Approach

Version identifiers are defined inside the resource link that in this case is the URL of the resource. Simply add the version identifier right after the entity that you want to version. The first thing that you have to version is the Resource Root that in this case it is the REST API. Add the identifier right after the API name and you’re done. API name can also be a name inside the domain, for ex: “scatter-api.foo.com”. The API version identifier is also called the Resource Master Version Identifier (RMVI). The next step is to version the Resource Instances of the URI. Every entity other than the root API name and resource version identifiers is called a resource instance. For example, The URL:

“foo.com/lib-api/v1/books/75/revisions/r2”.

The names ‘revision’ and ‘revisions’ are Resource Instances (RI) of the URL, and ‘75’ and ‘r2’ are the Resource Version Identifiers (RVI) of the immediate resource instances before them. The last resource instance on the right side of the URL is called the Primary Resource Instance (PRI), and the last resource version identifier is called the Primary Resource Version Identifier (PRVI). The PRI of the above URL is ‘revisions’ and the PRVI is ‘r2’. Request parameters can only come after PRI or PRVI:

“foo.com/lib-api/v1/books/75/revisions?action=rmv&id=2”,

OR

“foo.com/lib-api/v1/books/75/revisions/r2?action=rmv”.





The URI approach is good in caching and bookmarking for multi-version resources and that is because every version is accessible and identified distinctly with a URL and therefore there is no conflict. But it is not so in Header Approach and conflicts may occur. This will be uncovered soon.



Header Approach

Version identifiers are defined in the http header and are sent back and forth during content negotiation between REST API and REST clients. Version information are extracted from incoming http headers, and set by constructing the http header of the http request object. Let’s take a look at an example, The URL/Header would be:

URL: “foo.com/books/75/revisions/r2”.

Accept Header: application/vnd. lib-api-v1+json






URI or Header Approach?

Like all things it needs a trade-off, check your requirements and follow trade-off tables that already mentioned and you will find the best method for your REST resource versioning. There is a huge debate in community regarding which versioning method to use. Among these versioning methods there is no method better over another and each method should be used in its own place based on the design and requirement and future scalability and other factors. The URI approach is recommended based on the trade-off tables; maybe that is the cause that famous APIs use this approach. But the Header approach is also recommended if things become better about the required tools and that the software/server support is added to process headers in caching and bookmarking layers.



Misconceptions





Recommendations





URI versioning configurations:








Header versioning configurations:


In this configuration, the version info is in the http header. The server and client can be set up to support multi-representations using these headers. The server publishes the available representation formats and the client sets up a header and requests the related resource.









Parameters in URI versioning

The best practice is that you should not include any parameter other than version identifier in the URI sections as long as you are sure that the parameter cannot be declared/named a resource; instead, append the parameters to the URI. The following example provides some parameters and tells a REST resource to render itself in a particular language or in other words provides the same resource in another language:

URL: http://foo.com/scatter-api/v1.2/manual?lang=en&target=mobile

If you were to use a parameter like ‘en’ for English language in the URI section, then it would be the following hyperlink which is not recommended:

RUL: http://foo.com/scatter-api/v1.2/manual/en?target=mobile&from=12&to=22

It is a good practice to only end URIs with a resource name or index of the resource or a version identifier of the resource (which is somehow an alias to the resource) - therefore the URI should not end with a parameter. Parameters should always appear in the Request Parameters section that start with question mark ‘?’ and separated by ‘&’.



Parameters in Header versioning

In this case the parameters can be either in the related header or it can be included in the URI request parameter section. The following example shows the language parameter in the accept header:

URL: http://foo.com/scatter-api/manual

Accept Header: application/vnd.scatter-api-v1.2+json ; lang=en



Version Deprecation

In REST, all you have to do is to update the links of the next and previous versions of the resource metadata and update the ‘IsDeprecated’ property of the current resource version. All other tasks should be handled by service/state-machine business logic.



Conclusion

Currently I recommend URI approach for versioning because it fits all the scenarios well and there is no scenario that it cannot handle and that it is clear, simpler, testable, practical, and can be bookmarked and cached with no trouble when you have multiple master versions- but it is up to you to choose which method best serves your design goals of your company. For versioning strategy I would recommend supporting the previous version and mark old functionalities as obsolete before excluding the version from API support so that the development teams can get enough chance to upgrade to new versions.