Discovering the Value in Discoverable APIs

Inspired mostly by the article at BitNative, a great article on the difference between the original REST proposal and real world implementations. One of the main ideas that is least implemented (at least from what I’ve seen) is the “discoverability” idea – where each REST resource also includes a list of one or more additional actions that can be performed with that resource. I think there’s two main problems with discoverability in REST APIs that holds back most APIs from implementing the idea.

Definition of Discoverability

As a quick summary, the definition of RESTful discovery in an API. The general idea is any time you get a resource from a REST API, it returns (in addition to the resource) a list of references to related calls. You could imagine if you got a customer for example, you might also get a URL to get that customer’s sales history, or a URL to edit the customer along with what fields can be edited, or a URL to delete the customer. By defining these actions along with each resource, you could very easily build a client that could simply traverse the resources at an API and perform any of the actions it was told it could do.

So what’s the problem with this discovery concept? First off, is a lack of any sort of standard. There are a few examples of discoverability available in APIs, OData being one I can think of off the top of my head, but they all have their own implementation of discoverability. As an API author, it’s hard to get an idea of where to start with discoverability when there’s no real “shining example” of how it should work.

API Browser > Custom Client?

The other thing that makes it difficult, and what I think is the bigger issue, is imagining a client that would work well with this. I think the original idea behind discoverability was that you could have a “RESTful client” that could in theory work with any REST service that implemented discoverability. It would be simple to get a resource and immediately know the actions you could perform on that resource. But in practice, could you imagine the user experience? You’d have to make a lowest common denominator client – imagine using the exact same app to interact with both the Twilio and Twitter APIs.

Client applications, the apps that consume and expose these REST endpoints for users, are usually where all the usability and creativity lie. These are the highly designed and usually API-specific user experiences designed for a specific subset of users. When you fire up TweetDeck, you get an experience that is tailored for the kind of Twitter user you are.

One Client to Rule Them All

Let’s look at the opposite – a REST client app. Not one that’s built for any one specific API, but one that can consume all discoverable REST APIs. You can’t give any sort of targeted experience, because your userbase is now “everyone who wants to use any API”. You can’t really get too inventive on the design or experience side of things, because you have to support all resource browsing and entry scenarios. What you’ll end up with is a generic “here’s some links” or “here’s a dynamically generated form” application. Something that looks like the default Rails or ASP.NET MVC scaffolding.

Imagine using this instead of TweetDeck (Sesame Data Browser)

One API, Multiple Experiences

The existing client apps are designed around the existing functionality of APIs, and when something is new or changed in that API, the client app is updated with new features. I have yet to see an application that would really benefit from being able to automagically support new resource functionality. And when there is new funcitonality, a decent app would actually design a UX around it and release an update anyways, instead of risk showing a generic form to the user.

In summary, while discoverable REST APIs are a great idea in theory, I don’t think they have any value in a end-user scenario. Client app developers want to give custom experiences (indeed, this is their main differentiator), and end users don’t want a resource catalog browser.