= Building an API: Best Practices =
//**Update 25 Sept 2018: As a commenter points out, this 2012 article 'has not aged well'. I agree, and while I hope to update it at some point in the future, please see the comments ( and add comments!) for more modern best practices.**//
This doc outlines a few thoughts and best practices for building an API. This is based on my own experience building APIs, as well as examining popular APIs such as [[http://dev.twitter.com/doc|Twitter]], [[http://www.twilio.com/docs/api/rest/|Twilio]], [[http://developers.facebook.com/docs/reference/api/|Facebook]] and [[https://developer.foursquare.com/|foursquare]].
Be sure to check out these resources for more on API development:
* [[http://www.apigee.com|APIGee]] offers some great free API testing tools.
* The [[http://www.programmableweb.com/|Programmable Web]] offers a directory of public APIs.
=== REST vs. SOAP ===
One of the early decisions you'll need to make is whether your API will be 'RESTful' or use SOAP. SOAP is a protocol ('[[http://en.wikipedia.org/wiki/SOAP|Simple Object Access Protocol]]') and is generally used for more complex 'enterprise-level' APIs. It requires that you POST a specially crafted SOAP message to make the request, and then decode a second specially crafted SOAP message when the results come back. In contrast, 'RESTful' APIs are typically accessed by simply calling a URL and passing parameters ( ''http://api.mysite.com/getuser?username=david'' ), and then decoding the results from some agreed upon format, such as JSON or XML. **Unless you have some reason not to, you want to build using a RESTful model; nearly every major public API today does this.**
//Note: To be fully RESTful, an API has to do a lot more than be accessible via a URL; APIGee has [[http://blog.apigee.com/detail/does_your_api_need_to_be_truly_restful/|a good blog post with details]]. I believe in a 'pragmatic RESTful' approach; e.g. its OK to break some of the rules of REST for the purpose of being practical.//
=== JSON vs. XML ===
Now that you've decided on your API will be RESTful, you should decide how you're planning to return data. There are two common choices: [[http://en.wikipedia.org/wiki/JSON|JSON]] or [[http://en.wikipedia.org/wiki/XML|XML]]. The world seems to be moving to JSON; for example [[http://blog.programmableweb.com/2010/12/09/foursquare-api-v2-is-public-v1-deprecated/|FourSquare dropped XML support]] in its latest V2 API. XML is harder to parse, and it can't (easily) be parsed in JavaScript. There are JSON encoders and decoders for nearly every language, including non-web languages like [[http://code.google.com/p/json-framework/|iOS's Objective-C]].
Many APIs today offer a 'format' argument; for example [[http://code.google.com/p/bitly-api/wiki/ApiDocumentation#Request_/_Response_Formats|bit.ly's API offers]] a ''format==json'' paramter, and Twilio [[http://www.twilio.com/docs/api/rest/response|allows you to append]] a ''.json'' to any call to get the response in JSON format. Think long and hard before you do this: it increases your coding & testing complexity, and doesn't usually add much value unless you need legacy compatibility. I generally just use JSON.
=== GET & POST (and PUT, DELETE, etc.) ===
Another decision if you're using a RESTful model: do you use GET or POST for calls? I'd strongly recommend you follow the HTTP & REST standards; e.g. use GET for all calls for retrieving data (getUser, getObject, etc.) and POST (or PUT) for all calls where you send data (addUser, updateUser, etc.). You can also use other less common methods such as DELETE if you need to do an operation like removing a resource.
=== Use an Envelope ===
You'll generally want to wrap all your API responses in an 'envelope' which specifies metadata about the API call.
// sample JSON envelope
{
"status": {
"code": 200,
"message": 'Success'
},
"response": {
...results...
}
}
Doing this allows for client handler code to behave the same way for all API calls, since it gets a responses back in a universal format.
=== Handling Authentication ===
Most APIs you build will require some sort of authentication. Generally you want to implement one of the following:
- Use an established authentication standard, like [[http://oauth.net/2/|oAuthV2]].
- Roll your own token based authentication; you pass a username and password to an authenticate call and it returns an auth token, which the client app then passes on all subsequent calls. You might also consider session-based authentication; you call the authenticate call and it establishes a session, and all you have to pass back is the session identifier (which is frequently handled automatically).
- Roll your own [[http://httpd.apache.org/docs/2.0/howto/auth.html|HTTP Auth]] based authentication.
I don't have a strong preference. Foursquare, Facebook and Twitter all went the oAuth route, and it's clearly an emerging standard, but it seems particularly useful for social applications & API designed for application-to-application communication. Many other APIs use their own authentication scheme, and a few use standard HTTP authentication.
=== Handling Errors ===
Errors in APIs are an interesting beast. There are generally two ways to handle them, and they're not mutually exclusive: you can either return an HTTP status code if something goes wrong (e.g. '400 Bad Request' if a required parameter is missing ), or you can always return '200 OK' and pass the error back as part of the return envelope. I'm not really sure which one I prefer, although I've generally tended toward the latter.
There are also a number of cases where both are done; for example the foursquare API [[https://developer.foursquare.com/docs/overview.html|provides HTTP status return codes and then also sends those codes in the response body.]] Even more interesting, bit.ly actually [[http://code.google.com/p/bitly-api/wiki/ApiDocumentation#Request_/_Response_Formats|changes the handling of error codes]] depending on the return type (''txt'' vs. ''json'' vs. ''xml'').
=== Versioning ===
You'll almost certainly want to version your API so you can make changes in the future without breaking your existing clients. I recommend a version string at the root, e.g.
http://api.mysite.com/v1/
http://api.mysite.com/v2/
=== Developer Key ===
You might consider making your clients register for a 'developer key' (a.k.a. 'client key' or 'application key'). This lets you objectively track what apps are using your API, and also lets you block the bad apples if need be.
One interesting strategy here is BART's: they provide [[http://www.bart.gov/schedules/developers/api.aspx|a 'public' application key that everyone can use]], but threaten to rate-limit or cut it off if it's abused. Then they allow you to signup for a private key too.
=== Usage Limits ===
You may want to put some usage limits on your API, depending on its purpose and intended audience. Nearly every public API has rate limits, from Facebook to foursquare to bit.ly to Twitter.
=== SSL vs. Not ===
There's often a question of whether to use SSL to secure your API; I generally recommend the same thing I do for normal websites: use SSL if you have personal (non-public) data; otherwise don't.
SSL generally adds a 10%-15% overhead to a web transaction, so its not significant enough of a penalty if you need to use it, but its not so insignificant that you'd want to use it all the time.