I've been thinking a lot about APIs and their design recently.
I stumbled on this fantastic quote from Greg Parker:
A programming language is a user interface for developers. Language authors should learn from HCI principles.
— Greg Parker (@gparker) February 22, 2012
When I first started learning C++ (back in the bad old days) I was convinced that any 1st year student could design a better programming language. One which behaved in a sane fashion without a lot of legacy cruft. In many ways, PHP is that programming language. It's simple, logical, and works without having to know lots of esoteric computer science.
I see API design in the same way. Most of the APIs I come in contact with were obviously designed by the original developer for the original developer - with no thought of those who would come after her. Often, they're designed for one specific internal usage, reluctantly opened to the public, and never updated to account for how people actually use them. Oh, and you can forget about decent documentation!
One hackathon I went to a few weeks ago had a Developer Relations employee stand up and say:
Who wants to use our API? It uses SOAP - sorry. If you want documentation - come see me because it's not on the website. Oh, and it's read only. Let me know as soon as possible because it takes 6 hours to approve your API key.
This is madness. Developers are human too! They need some HCI love between them and their APIs.
So, here are my hastily scribbled thoughts on what an API needs at a minimum to entice the busy developer.
I don't think any of these are Earth-shattering, but it's amazing how many APIs fail to meet even these basic requirements.
- Don't make me register, set up an account, or fill in a load of forms - I just want to see what I can do with you before I make a commitment.
- Do give me an Apigee console - or similar - so I can see for myself what's happening.
- Don't give me absurd key signing requirement - I should be able to call the API from a web browser just by typing stuff in.
- Do make it as easy as possible for me to get started - get your CEO (or similar) and see how long it takes her to set up an account & launch her first call. If it's more than 5 minute, go back to the drawing board.
- Don't tell me what your API can do - show me a few cool calls to start me off.
- Just because you love Ruby, doesn't mean everyone does. Show examples in a variety of languages.
- Provide examples of code which won't work and explain why.
- Comment your code. It may be obvious to you what "choes=17|L" means, but it may not be to me.
- This is possibly the most important area.
- I need to know what I can do, how I can do it, why I should do it a certain way, and what response to expect.
- For. Every. Single. Function.
- If you can't document your API, people can't use it.
Full Enumeration of Responses
- Tell me the full range of response I can expect.
- A good example is Twitter's "retweet_count", the documentation used to imply that the response would always be an integer. However, it would occasionally respond with a string of "100+". Naturally, this meant developers would write code expecting ints which would fail whenever a string was encountered. If you can't tell me what responses to expect - how can I code something which handles those responses correctly?
- What error codes are you likely to throw?
Variety of Response Language
- Yes, you love XML. Guess what? I don't!
- The customer is always right. If the customer (developer) wants JSON, XML, PHPobject, or just plain text - you should give it to them.
- It's the API designer's job to make life easy for developers - so reply in whatever formats the developer wants.
Human Readable Response
- Developers are humans! Yes! It's true! And they can't all pretty-print JSON in their heads. Give them something they can read without resorting to external tools.
- The Wikipedia API is a brilliant example of this. They have a human readable response for their API calls.
- Unless you have a very good reason not to - all your responses should be pretty-printed. It helps with debugging and makes life just that little bit easier for a struggling developer.
Human Readable Requests
- Developers are humans! Yes! It's true! And they can't all remember every little acronym in their heads. Give them something they can read without resorting to documentation.
- What's easier to remember "gnxID" or "getNextId"?
- Keep your parameters consistent.
- Consistency is a virtue. If you have two similar APIs (say, search & read) they should take the same parameters and produce identically formatted responses.
- If you have to change the way your API responds, or the way it accepts request, that's fine - but use versioning so that developers don't have to update their code if they don't want to.
- Never deprecate anything! Once an embedded device has had its firmware burned, it's unlikely to ever be updated. If people or services rely on you, it's simply unacceptable to kill something off. Remember, not every developer or end user can update their software.
- Perhaps the most important of all HCI commandments - Keep It Simple.
- Don't engage in a needless dance where developers have to take several steps to do a single action.
- Try to explain what you're doing in a single sentence. If you can't - it's probably too complicated.
- I'm sure you're very proud that your community has created some libraries - but they're not good enough.
- Want people to use your API? Provide libraries in a wide variety of languages.
- Update and support those libraries.
- It's not enough to say an error has occurred. Say why it has occurred.
- Error codes must always be accompanied by human readable error messages.
- Do you really need to throw an error? Can your API take a "best" guess at what the user was trying to do? Be generous in what you accept.
- Your API sucks. Accept that.
- Provide a mechanism where people can feed back what they think is broken, poorly implemented, missing, or just plain confusing.
- Discuss the feedback openly. See what the rest of your community thinks.
- Act on feedback. If a feature request hasn't been acted on after 6 months, you've probably failed.
There is nothing new in this post to the seasoned developer. But as Matt Gemmell reminded me recently - some people just don't know the basics.
If you're interested in making your API useful for developers, you have to treat it like any other product. You have to consider HCI factors, you have to do product testing, design, and planning.
Your API is a product. Treat your developers as you would your most profitable users.