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

10,416

Solution 1

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.

Solution 2

The cleanest way I know is by using profiles. There is an IETF RFC for that (RFC 6381).

Using the accept header, indicate what type of response you expect. You can still use qualifiers as well. You can request compliance with one or more comma-separated profiles, but you must use quotes if you specify more than one profile.

Accept: application/json; profiles="http://profiles.acme.com/user/v/1"

Using the content-type header, the server can respond alike:

Content-Type: application/json; profiles="http://profiles.acme.com/user/v/1"

Share:
10,416

Related videos on Youtube

PatrikAkerstrand
Author by

PatrikAkerstrand

I'm a front end engineer at www.aftonbladet.se, Sweden's largest newspaper. Programming languages PHP JavaScript Java C# Databases Schema design MySQL, PostgreSQL Web servers Apache Frontend xhtml, html, css Prototype, JQuery, YUI3 YUI3 Grids

Updated on June 24, 2022

Comments

  • PatrikAkerstrand
    PatrikAkerstrand almost 2 years

    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
      }
    ]
    
    • David M
      David M almost 12 years
      +1 for the link to that presentation if nothing else. Thanks.
  • PatrikAkerstrand
    PatrikAkerstrand almost 12 years
    Thanks. When it comes to deciding between a qualifier and a new media type, which one would you prefer for versioning and why?
  • William Durand
    William Durand almost 12 years
    I would use the qualifier to avoid modifying the content type. It's just a matter of taste I guess.