APIs are boring. They are passé. No, really.

In an episode of Progressive Enhancement, Paul Downey referred to APIs as the "tradesman's entrance" to a website.

Here is the problem.

Let's take a nice, cynical tweet I posted recently.

It is located at http://twitter.com/tommorris/status/5594080828

Only, that's the HTML version.

There is an XML version available at http://twitter.com/statuses/show/5594080828.xml

And there's a JSON version available at http://twitter.com/statuses/show/5594080828.json

This is totally unnecessary. You've heard of REST, right? It's one of those cool Internet buzzword things people talk about. I won't try and explain it. I'll just point out the first lesson of REST, which also happens to be the first lesson of the Semantic Web and Linked Data principles.

Think about your stuff like an object. If you were building Twitter in an object-oriented programming language, you might have a Tweet or Status class (the name isn't important). But you wouldn't have a StatusXml class, a StatusHtml class, a StatusJson class and anything else that came to mind. You'd have one class: Status. It's one thing.

If you are building a web service, think about every thing you create - every object. Those can be classes that are instantiated thousands of times or singleton objects instantiated once. The URI is like the hashcode of the object - one object = one URI.

These objects can have various representations, just like objects in an OO language can have various serializations. Most objects will have a toString() method (in Ruby, it's called to_s, in C#/.NET, it's called ToString() etc.) - in web-land, this is your HTML. This is your main representation.

But you aren't limited to just that representation: you can have many, many representations of the same thing. Here are a few to choose from:

Let's take our tweet again: how could we represent that:

For media sites like YouTube or Flickr or AudioBoo, here is another one to add to the list: the raw media file binary.

I don't want an API. What I want is for every site that would think about having an API to structure their site in an object-oriented way and to provide as many different representations of those objects as is practical.

Why is this a good idea?

Firstly, it reduces the amount of re-learning one has to do. If you know how to use the Web in a programmatic fashion, you know how to use an API which works in this manner. There's no having to read the documentation for Flickr or Twitter or identi.ca - because there is no "Twitter API" or "Flickr API" - they just inherit the HTTP API and the architecture of the web.

But how does this work? It uses a principle that's built into HTTP called Content Negotiation. Content Negotiation is what makes HTTP more interesting than, say, FTP or Gopher. See here for more details. Content Negotiation works like this: When you send a request to a server, it asks for content of a specific type. In most cases, your browser will say to the server "give me HTML" and that's what the server does. But it doesn't have to be HTML. You can ask it for anything. In fact, you can give it a weighted list of what you want and it'll try and give you what you want. Don't worry, though, the server should tell you what type of content you are getting back. If you ask for Atom and it gives you back generic XML, it'll tell you in the header. To carry on with our OOP analogy, imagine if you had a method like this: serializeAs(Class class). This is what you are saying to the server: you are saying 'give me back this object as a _whatever_'. Then the server will say 'here you go, here is the object as a _whatever_'. Only, the whatever may not be the same.

The key to this is the Accept: header. The Accept: header takes a MIME type. So, map out the potential return types you want to give and find the relevant MIME type. Content negotiation is supported by plenty of different frameworks - Rails does it really well with respond_to.

But not everyone gets content negotiation, so it's often wise to provide some fallback.

There's generally two ways of doing this. Either you can use file extensions or you can use an 'output' parameter.

Twitter is an example of using file extensions - even if they messed up and made the URLs different in other ways. File extensions are just a convenience. The resource is still the same, but you are providing a convenient way for people who don't understand content negotiation to get to the content.

Output paramters are the other way of doing it. Instead of having /foo as the resource and /foo.xml, /foo.json and so on as the file extension 'shortcuts', you just add on an argument called output - so you get /foo?output=json

(tbc)

Powered by WiGit