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

PatrikAkerstrand picture PatrikAkerstrand · Aug 20, 2012 · Viewed 10.3k times · Source

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
  }
]

Answer

William Durand picture William Durand · Aug 20, 2012

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.