21 September 2011
Another post about APIs, I know, but the more projects I work on that depend on APIs the more experienced I get with the pitfalls and common stumbling blocks of using public APIs as the backend for an application. With experience comes opinion and, as those who know me can tell you, I’m never quiet about voicing mine.
The way forward
First, let me say that I really do think that breaking your applications into completely separate (and differently scaleable) parts is just good architecture. The idea of having one service that provides a public API and multiple clients that all use that API makes great sense in this web/native mobile/other devices you’ve never even heard of world. It’s easy to add new clients in the future if you want to add an iPhone app, or an Android app and it’s even easier to maintain your service since your app is broken into clearly defined and delineated sections, each with their own function. Way of the future, boy, way of the future.
What is he talking about?
But building apps that hinge on a public API mean that you can’t rely on ActiveRecord to return your data in nice, neatly packaged objects ready to use in your Rails web app. At its best your API will return perfectly formed, correctly typed JSON or XML data for you, but at its worst, you might get your responses in a few different forms, with no discernible pattern and with a slew of different HTML content-type headers. This is bad, very bad. It means that any client, be it a web app or an iPhone app, has to parse each response differently. It means that instead of a common standard you have a bunch of unrelated and difficult to predict responses to remember, code for and to maintain into the future.
Plan, then Execute
Ok, ok, so you’ve bought into the whole public API/multiple clients model. First things first, build your API. No! Stop! The first thing you need to do is decide on a couple of key factors.
What format are you going to return? This is an important one, are you going to return XML, JSON, or something else entirely. Be clear from the beginning and stick to your guns once you’ve made your choice. I would suggest JSON since it’s easily parseable, concise and requires less data to transmit down the lines.
Your responses need to be consistent. Decide on a format of response early on and don’t change. What I mean by this is that you should decide how you’re going to return errors, how you’re going to return your data and how you’re going to handle message and response codes from the outset. Look through a few popular APIs to get a feel for how they are returning data (Twitters API is a good one).
Your data model needs to be consistent. This is different from the response. If you call your users “users” in one context and “members” in another you’re doing it wrong. Likewise, the fields on your models should try very hard to remain consistent. If your Users have a first_name column in the database don’t return that information as first_name when the API consumer asks for a User and f_name when the User is returned with the Post that the API consumer just requested.
Details matter. Check that your responses are returning the right content-type and response code headers. It’s not enough that you put the HTTP response code in your JSON response, do it properly and set it in the HTTP headers as well. There is great Google Chrome extension called Advanced Rest Client that can help you debug your requests and responses.
Putting your planning time in at the start can really help you down the line so don’t skimp. You’ll be much happier developing all those sweet clients if your API returns all your data in a consistently easy-to-process format.