One of the things about working with data at 37signals is that I end up interacting with a lot of different APIs—I’ve used at least ten third-party APIs in the last few months, as well as all of our public APIs and a variety of internal interfaces. I’ve used wrappers in a couple different languages, and written a few of my own. It’s fair to say I’ve developed some strong opinions about API design and documentation from a data consumer’s perspective.
From my experience, there are a few things that really end up mattering from an API usability perspective (I’ll leave arguments about what is truly REST, or whether XML or JSON is actually better technically to someone else).
Tell me more: documentation is king
I have some preferences for actual API design (see below), but I will completely trade them for clear documentation. Clear documentation includes:
- Examples that show the full request. This can be a full example using
curllike we provide in our API documentation, or just a clear statement of the request like Campaign Monitor does for each of their methods.
- Examples that show what the expected response is. One of the most frustrating things when reading API documentation is not knowing what I’m going to get back when I utilize the API—showing mock data goes along way towards this. Really good API documentation like this would let you write an entire wrapper without ever making a single request to the API. Campaign Monitor and MailChimp both have good, but very different takes on this.
- A listing of error codes, what they mean, and what the most common cause of receiving them is. I’m generally not the biggest fan of the Adwords API in many ways, but they are a great example of exhaustively documenting every single response code they return.
- A searchable HTML interface. Whether it’s visually appealing doesn’t really matter much, and Google indexing it is plenty of search. What doesn’t work for me is when the API documentation is in PDF, or I have to authenticate to get access to it.
- Communication of versioning and deprecation schedules. There’s some debate about whether versioning is better than gradual evolution, but regardless, anytime you’re changing something in a way that might break someone’s existing code, fair warning is required, and it should be on your documentation site. Sometimes you have to make a change for security reasons that don’t allow much advance notice, but wherever possible, providing a couple of weeks notice goes a long way. The Github API clearly shows what will be removed when and shows the differences between versions clearly.
Let me in: all about authentication
Most APIs either use OAuth/OAuth2, user/password or API token via HTTP basic or digest authorization, or a special parameter included in each request. These all have advantages and disadvantages:
- OAuth and the still developing OAuth2 are becoming the defacto standard for any API that primarily expects the API consumer to be a third-party application. It’s secure, relatively consumer-friendly, and relatively easy to use. The downsides: implementations vary slightly across service providers (I often hear that “the documentation is the implementation”), and it’s a lot of overhead for something where you just want a single piece of data.
- User/password or special API token via HTTP basic or digest authorization is fast, doesn’t require anything more than
curl, and you can even make some request from a browser. The downside here is that it’s not especially “friendly” to ask an end-user to go find an API token.
- User/password or API token as a URL parameter fortunately isn’t very common. It’s more confusing than basic authentication, has all of the same downsides, and no real benefit.
There’s clearly a tradeoff here—OAuth is great for delegating authorization for a third-party, but API tokens are better for quick access to your own data. My preference is for an API to offer multiple methods of authentication so you can choose the best method for what you’re trying to do.
Underlying design: REST or something like it
There’s a formal definition of REST, and endless debates have erupted over whether a given API is truly RESTful or not. As a consumer of APIs, I don’t really care whether it’s technically RESTful, but there are a few “RESTlike” attributes that do matter:
- Not SOAP. I know there are legitimate reasons to have a SOAP API, and I can imagine that translating a massive API from a legacy SOAP to REST interface is quite difficult, but it’s incredibly difficult to consume SOAP if you have to develop a client library from scratch or do anything non-standard.
- Use HTTP verbs to mean something. Any API consumer is capable of sending
DELETEverbs, and they greatly enhance the clarity of what a given request does. It’s terrifying to use an API where a
GETrequest can change the underlying data.
- Sensible resource names. Having sensible resource names/paths (e.g.,
/api?type=posts&id=23) improves the clarity of what a given request does. Using URL parameters is fantastic for filtering, but if everything is based on a single API endpoint and tons of parameters, the mental model required to use it gets too complex very quickly. I really like the way Assistly’s API has implemented resource paths and uses HTTP verbs.
- XML and JSON. I like JSON. Some people like XML. Unless the costs of offering both are staggering, offer both. Ideally, you’ll let me switch between just by changing an extension from
- Use abstraction where it’s helpful. Your API implementation does not have to mimic your underlying application architecture. For example, the Adwords API has 25 distinct “services”, each of which seem like one module of the underlying implementation. This is logical if you implemented it, but that doesn’t make it particularly friendly to use—if you wanted to retrieve your click through rate for each ad you’re running, you’d end up making (literally) dozens of distinct requests. On the other hand, the Google Analytics data export API lets you define reports so that you rarely have to make more than one request, but you’re still only fetching what you need. If you think there’s some common action that people will go to the API for, you should make that action easy, even if it means compromising on ideology.
These are my preferences, and there are no hard and fast rules of API design. Regardless of whether you apply any of these principles in your next API, I would absolutely encourage you to look at your API from the standpoint of a consumer. Maybe try building something small using your own API – it can be an eye opening experience.