Ask HN: What makes an API good?

67 points by relaunched ↗ HN
I've consumed a great deal of major, public facing APIs over the years, some I've liked more than others. However, I'm writing a series of APIs for a new project, and ahead of starting I've documented the things I like about some APIs and things I don't about others. For example, uri construction, documentation, response time, flexibility, code samples and organization of taxonomy help me differentiate good and bad.

I thought I'd ask, what do you think makes for a good api?

67 comments

[ 4.9 ms ] story [ 133 ms ] thread
Consistency, predictability, documentation, reliable sample client in a couple of popular languages (e.g. PHP, Python, Ruby), well abstracted.
Documentation is 1000x above anything else. This includes sample project(s).

Documentation is without question the deciding factor of whether I'll use a service.

Besides that, I care about support channels, adherence to standards (i.e. correct HTTP status codes), and as few hoops as possible to jump through to start (i.e. a curl command to get my auth key, and away I go)

Very true, but it needs to be a specific type of documentation - namely something that explains how to use the API rather than what the API endpoints are. By sitting down and writing about what's needed to get the most out of the API, as well as writing extensive code examples, you're forced to think about how people are going to use the API. Any problems, quirks or bugs should be obvious at that point because you're using the API as it'll be used by other developers. Simply listing the endpoints with what parameters they need and things they'll return won't make your API better.
How much documentation did you get, when you got your Mercedes Car. The stress on Documentation is a little overrated in my humble opinion. If the Tools are made intuitive and the API is made as a natural way of thinking and progression of the state of the Message, The API speaks for itself, and the Developers engagement would be at its peak. If you have to read a Documentation before applying your Brakes on a car, you might as well be too late. Adherence to Standards and not letting unexpected happen and get out of the way of the developers work process is the way to go.

Having said that, If you are on the leading edge of software which no one has attempted before, or trying to create a Market, Thats when your Documentation would explain those edge cases better to gain appreciation of your point of view.

The main thing about creating a good API is that you have a good relationship and good communication with the consumers of that API. I've seen a lot of people making internal APIs inside companies treat it as another way to throw something over a wall.

There's very little universal about a "good" API design. Even response time might not matter if your users aren't using it synchronously. Best way to make an API is to have a plan to support old versions, release something early, see what people make of it and incorporate their improvements. Worst way to make an API is to try and think of everything before you start - you will fail and you'll take a long time

been in this position! I feel bad thinking about it now!
One vote for good documentation.

Not just a link to the Javadocs; preferably a "getting started" page that covers the most common use cases with plenty of plug and play examples (if such a thing is even possible in your case).

Also, getting back to the API reference, I'm grateful when there is a roadmap or overview of the class/package structure so I don't have to crawl through the entire thing.

>Not just a link to the Javadocs; preferably a "getting started" page

I wish more java projects had python-style documentation. I can probably figure out how to do things eventually by wading through Javadocs, but they can be really frustrating if all I need to know is how to accomplish the core activity of the project.

Among some, there is a certain "machismo" associated being able to make do with the API reference and nothing else. I think this is a waste of time, personally. I noticed this especially among the Rails developers I've worked with.
He talks primarily about a REST-Api not Code-Api. For Code-Api i prefer Javadoc too.

For rest-api https://github.com/apidoc/apidoc

Within the doc you can add examples for usage and response.

But a some common pages with Tutorials / HowTos are nice and should be added to a good documentation. (it depend on the complexity of your project and your audience).

Would be great if you shared what you've compiled as well. Thanks.
Aside from common things like "being useful" the key aspects of a good API (to me) are:

1. Expose 2. Wrap 3. Consistency

Expose what's going on under-the-hood. For example, an HTTP.Get function may do what's needed 98% of the time, but if you don't expose requests, sending, keep-alive, etc. then I won't be able to do the last 2% when I really need it. Part of exposing is factoring your functions well.

Wrap what's exposed to handle the most common cases. If I want to perform a GET request, I shouldn't be required to create a request, open a socket, issue the request, parse the response, follow redirects, etc. There should just be a simple HTTP.Get function that does all that for me with the common options as arguments.

Finally, the API should be consistent. Consistency covers a range of topics. The API should be consistent within itself: consistent naming, modules, etc. It should be consistent within the environment (e.g. don't use underscored function names in Go). But consistency also means future releases shouldn't break existing code unless absolutely necessary.

Versioning. Also, make sure that you're committed to supporting old versions of your API for the foreseeable future (the actual time period depends on the company - for Google, 20-30 years, while 3-5 years for a startup).
1) URL construction: KISS (Keep It Simple Stupid), or as Einstein said, "Everything should be made as simple as possible, but no simpler."

2) Documentation: Code examples, easy things like: "This is what you send, this is what you get." "If you change this, now you get this." Simple example heavy documentation. 1 example is worth a hundred lines of documentation.

3) Response Time: meh. If your at or around 100ms you don't need to worry to much. If people want ~50+ calls per second, then ask them what their use case is, or have them pony up money. Then worry about response time.

4) Flexibility: Largely over rated. You can waste a ton of processing power trying to figure out what the user meant to say. Most of it is wasted, if their query doesn't make sense return an error. Your performance will go up. This hooks into documentation, if your documentation is easy enough to understand you won't have to fuzz the queries.

5) Code Samples: See documentation.

Einstein said "Everything should be made as simple as possible, but no simpler" Your misquote means the opposite of what he said.
(comment deleted)
RE:documentation, Stripe does an awesome thing where they inject your API key and secret into the examples, so you can just copy and paste their example and go.

Its brilliant, and should be copied everywhere!

I'm also a big believer that really excellent, thoroughly commented examples are worth a thousand pages of documentation.

this! as a non-technical guy, I can even work with Stripe examples
2) Documentation: Code examples, easy things like: "This is what you send, this is what you get." "If you change this, now you get this." Simple example heavy documentation. 1 example is worth a hundred lines of documentation.

This is the only point that I care about (and 5) for being relevant). SO MANY TIMES I have tried to use an API only to find books of documentation without any working examples. Speak to me in the language your API understands, working examples, and everyone will have a good time. :-]

Its a major sin a lot of developer commit. I'll just write 400+ pages of documentation.

That's great. Nobody will ever read it. Make it enjoyable to read and interact with. I keep this XKCD over my desk for a reason http://imgs.xkcd.com/comics/manuals.png

Yes, examples are critical. It is possible, however, to make the examples TOO simple. I've seen this a lot in the documentation for libraries in the programming language R. The examples are so stripped down and abstracted from what you would use in actual work that you can't see how to apply them in a useful situation.
I like it when APIs offer good filtering options for searches. When all you have is basically "here is a list of things" + "here is a single thing with an ID", all you end up doing is scraping the entire list to do fun things.
Some things that irk me:

0. JSON. Use JSON.

1. Version your API

2. Any numerical value whose precise value you care about, send as a string.

3. Any ID should be sent as a string.

4. Any timestamp should be sent as RFC3339 UTC.

5. Any data whose numerical value matters (i.e., must properly include NaNs, whatever) should be sent as an encoded base64 blob.

6. Properly support HEAD, PUT, PATCH, OPTIONS.

7. Send back your response as human-readable JSON, with newlines and tabs. If you can't afford the bandwidth (protip: you can), then you shouldn't be using a text format anyways.

8. Allow me to change replies using accept headers and extensions on the URI. Document the order of precedence.

9. Understand the limits of the REST mental model for handling things--don't be afraid to have a few "ugly" endpoints.

If that data is ever to be viewed by a human you should focus on presenting the data in such a way that it is as easy as possible to display on the screen, if the process of getting the data to the screen is not easy the vast majority will either try to find an easier product to work with or just give up on trying to find a solution to that problem. (IT guys have a lot on their plate, and mountain of forgotten projects because they didn't have the time)
At 18F (a digital services consultancy within the US federal government), we've drafted API Standards[1]. They're a set of recommendations, rebuttable presumptions, and bright line rules that we expect our APIs to adhere to. For an organization that may offer several APIs, having a set of standards will help ensure, among other things, baseline quality and consistency.

[1] https://github.com/18f/api-standards

Agreed with all the previous comments.

URL Design is key. I often refer to the naming chapter of Uncle Bob's Clean Code book for this. This also helps with consistency and predictability, which in turn, makes writing docs easier.

I've got an API Design Readlist, which I've added this thread to. http://readlists.com/6c5c6009/

I highly recommend the following talk by Joshua Bloch: "How to design a good API and why it mattes" [1].

Key points:

- When in doubt, leave it out - you can never remove things from an API but always add to it.

- Write several clients of the API to get a good feel how its used. Three is usually enough, one is not.

[1] https://www.youtube.com/watch?v=aAb7hSCtvGw

Simplicity. As a consumer of your API I should not have to do anything I don't need to. The worst thing is when you have to jump through hoops to deal with an API that was clearly designed for the implementer's convenience, not yours.
The Heroku platform team has a good document about their API design guidelines:

https://github.com/interagent/http-api-design

That is a very comprehensive set of conventions! Contents pasted here:

Foundations - Require TLS, Version with Accepts header, Support caching with Etags, Trace requests with Request-Ids, Paginate with ranges

Requests - Return appropriate status codes, Provide full resources where available, Accept serialized JSON in request bodies, Use consistent path formats, Downcase paths and attributes, Support non-id dereferencing for convenience, Minimize path nesting

Responses - Provide resource (UU)IDs, Provide standard timestamps, Use UTC times formatted in ISO8601, Nest foreign key relations, Generate structured errors, Show rate limit status, Keep JSON minified in all responses

Artifacts - Provide machine-readable JSON schema, Provide human-readable docs, Provide executable examples, Describe stability

Consistency. pick a convention and keep doing things that way, always and everywhere.
If its a Java or object-oriented framework or library - follow SOLID principals and limit dependencies. Make it unit testable. Try to make it consistent - calls to get one type of object should be similar to ways to get other types of data, etc. Functional approach to the interfaces - pass in required arguments, get back result. Don't require user/developer to create several configuration or factory objects before they can call a simple method to get some data, etc. Don't require the use of dependency injection frameworks or other complexities. If its web-based API return data as simple JSON or XML without overly complex namespaces, etc. Name things consistently - the names of response objects and properties should be the same as the corresponding inputs, etc. Copy - look at a successful API or library which does something similar - then copy the way it works and the way its documented. Especially if the users/developers already know how to use that one...
I think it depends upon the use cases of the API, but if you want someone to be able to build snappy and fast "apps" using your API rather than just facilitating movement of data in/out for an integration with another piece of software, I think granularity is important.

Having built our front end using AngularJS, we are the first users of our own API and that has driven it's design. In order to make things quick, we really needed to trim down response payloads in some cases which kind of deviates from standard CRUD patterns in some areas.

This has come at the expense of good documentation (we have a lot more methods now and having good examples of all of them will be expensive) and consistency--things are not very uniform anymore. However, as an API consumer I'd rather have the API give me too many options rather than too little. Our API has gone from "pretty" to "very functional".

Sounds like you're going in the wrong direction. An undocumented, granular API with lots of options won't be used, so it won't matter how fast it is.
So this is why I said it depends upon your use case. We are an enterprise software company and there are probably less than 50 potential customers in our target market that could ever use the API.

We are one of the only companies that actually has an API. If a customer has a use for our API they'll get personalized support.