Versioning a RESTful API with both XML and JSON Content-Type

content-type, hateoas, http-1.1, json, rest

Solution

You can implement versioning either by adding a version in the content type:

application/vnd.acme.user-v1+xml

Or you can also use a qualifier in your `Accept` header, that way you don’t touch your content type:

application/vnd.acme.user+xml;v=1

You can split your content type `application/vnd.acme.user+xml` in two parts: the first one (`application/vnd.acme.user`) describes the media type, and the second one (`xml`) the format of the response. That means you can use another format like `json`: `application/vnd.acme.user+json`.

In the HATEOAS world, XML is better than JSON for readability and semantic purposes, if you want to use JSON, you could be interested by this specification: https://github.com/kevinswiber/siren.

Problem

According to this excellent presentation on designing RESTful interfaces, the preferred way to implement versioning is to utilize the Accept-header, using something like: ``` GET /products HTTP/1.1 Host: example.com Accept: application/vnd.com.myservice.v2+xml ``` This works perfectly for XML Content-Types, but is possible to use the same scheme for versioning the JSON-equivalent? I.e, is it possible to ask for: ``` GET /products HTTP/1.1 Host: example.com Accept: application/vnd.com.myservice.v2+json ``` The response would be something like: ``` HTTP/1.1 200 OK Content-Type: application/vnd.com.myservice.v2+xml; charset=UTF-8 Allow: GET, POST <?xml version="1.0" encoding="utf-8"?> <products xmlns="urn:com.example.products" xmlns:xl="http://www.w3.org/1999/xlink"> <product id="1234" xl:type="simple" xl:href="http://example.com/products/1234"> <name>Red Stapler</name> <price currency="EUR">3.14</price> <availability>false</availability> </product> </products> ``` and the JSON equivalent (sort of): ``` HTTP/1.1 200 OK Content-Type: application/vnd.com.myservice.v2+json; charset=UTF-8 Allow: GET, POST [ { id: "1234", links: [ { rel: "self", href: "http://example.com/products/1234" } ], name: "Red Stapler", price: { currency: "EUR", value: 3.14 }, availability: false } ] ```

Original source