Evolution of RESTful services

If you’re at a presentation and the presentor asks “Who used soap?”, and not all hands go up, you’re probably at a technical presentation. Earlier today some videos of the Symfony Live San Fransisco conference have been released into the wild, so I decided to take a look. One of the videos listed was about how to design RESTful Web Services. This one was interesting since recently two (internal) RESTful services have been delivered at the company I work for.

Obviously he had to explain the basics of REST first. After that he dives into the evolution of RESTful apis. What kind of change requests can you expect, and how can you anticipate on that? He made three very important points about that.

JSON vs XML

The first thing he argues is that JSON is bad, hmm’kay. Doesn’t evolve well at all. Say that you have a product object

{
  name: "Soap",
  price: 3.47
}

And you want to add the currency the price is in. In XML this would be an easy change, <price currency=”EUR”>3.47</price>. No clients would break, you’d only have to adapt them in case you want to benefit of the new information. In JSON your only option would be to turn this float into an object

{
  name: "Soap",
  price: {
    amount: 3.47,
    currency: "EUR"
  }
}

This will, unfortunately, break all of your clients. So now all clients would have to be adapted to handle this case. A similar story happens when a one-to-one relation changes to a one-to-many relation. In XML you’d just add one more price tag, in JSON you’d have to change the price to be an array of prices. So the chance of a change request being a breaking one is bigger in JSON than in XML.

How to deal with breaking changes

He suggests that every RESTful API should have it’s own custom media type. Basically the principle that clients request stuff like this:

Accept: application/vnd.com.acme.shop+json

This can be intepreted as “I’m requesting application data from the vnd.com.acme.shop application, the information I’m getting back is of type json”. Or use +xml if thats your game. Now if you introduce a breaking change, you can just apply the breaking change only when a new version of your API is requested:

Accept: application/vnd.com.acme.shop.v2+json

This enables releasing a new version of the API, and then slowly transferring the clients to the new version. Of course you can’t keep supporting the old version forever. Since our RESTful services are all internal and we know the clients using the service, this is a very practical way to go. For a public RESTful API things get a bit hairy. You’ll need a clear deprecation policy and logging to be able to identify and warn individual customers in a timely fashion that they should really upgrade to the new version.

Ah, and for the third point? The services we made are not really RESTful all the way. And that’s fine :-).

Leave a Reply

Your email address will not be published. Required fields are marked *