Wednesday, December 15, 2010

API Design

I recently presented some opinions and ideas about web API design at Salesforce.com's Cloudstock event in San Francisco.

In the talk, I start with a poorly designed API and iterate it toward a well-behaved REST API. Along the way, I compare APIs from Facebook, LinkedIn, Twitter, Foursquare and others and share my opinions about which APIs do things well and which don't.

If you're thinking about API design, please give it a view and let me know what you think.

Here is a studio version of the talk:

5 comments:

  1. Hi Brian, great talk. I have a few comments about it:

    1. Versioning: I don't think it's right to add /v1 to the leftmost part of the URL because that URL indicates a unique resource and the API version doesn't have anything to do with that particular resource. HTTP headers should be used in this case.

    2. Format: The format in which the returned data is should be determined by using "Accept" http header because that header is meant to be used for accepted format of data. The same with versioning, an 'extension' is not part of the resource itself but with its representation.

    On the other hand, "Content-Type" is not meant to be used for returned data, but for the format of the data of the message being sent, not the format of the data of the returned message.


    Rodrigo

    ReplyDelete
  2. Hi Rodrigo,

    Thanks for the comments.

    Your point about the difference between "Accept" and "Content-Type" is important. I (embarrassingly) didn't understand the difference, thanks for clarifying.

    Your suggestions are clearly true to HTTP & REST principles. Whereas, my opinions deviate from them.

    However, as a practical matter, for the reasons I enumerate in the talk, I believe they represent solid design trade-offs for broad adoption of APIs that are version-aware and format-friendly.

    ReplyDelete
  3. Hi Brian

    I like the talk though we differ on quite a few things one area we are in strong agreement is around simplicity and discoverability of the API.

    You mentioned in the section on formats your recommendation that the API should be addressable via a uri extension i.e. ".json" and not via headers. You also said that if an API supports both you are not sure which takes precedence.

    The answer is the accept header always takes precedence. However the server is really free to do what it wants regardless. For example if I sent an accept of "application/xml' to "order/1.json", the server could do one of the following.

    1. return json
    2. return xml
    3. return a 406 Not Acceptable
    4. return anything else

    It's really up to the server to decided.

    On the same note, there is nothing wrong with supporting bookmarks to a specific representation i.e. orders/1.json. It is helpful for many scenarios as you mentioned.

    The advantage however of supporting accept is it provides a standard "protocol" for asking for a specific representation. It allows the server to evolve to support new formats and lets standard HTTP clients request it without having to know about the servers uri space.

    For example, you might look at your logs and see clients are looking to get that order back in PDF form by sending an "accept: application/pdf". You see that and say oh, some clients wants to see an hardcopy of the original order.

    Great, we'll add that to the system, so you then update your system accordingly.

    After the update, the next time that client comes and sends that accept, it gets back the PDF. That same client may interact with different servers, the beauty of accept is regardless which server it talks to it uses the established protocol of content negotiation via accept.

    Now as you mentioned there are plenty of developers that won't care about this. For those I would support the simple bookmarks. However, for develoers / systems that do care (and there are plenty) I would recommend supporting conneg.

    It's not an arcane esoteric science, it's how all the most popular web servers and proxies work today. :-)

    As far as the item resource being plural. "Makes sense" is in the eye of the beholder. While you can make the argument that it makes sense to make it plural, I have equally seen many folks that believe the opposite makes sense.

    Personally I don't care which way you go, and I don't think it diminishes the quality of your api by having s or not in the uri name.

    Lastly I'll push back on your you only need 2 root uris. I'll argue you only absolutely need one, but that makes an assumption that you are building a hypermedia based system, which has plenty of other advantages.

    Thanks

    ReplyDelete
    Replies
    1. awesome, thoughtful reply. thanks for taking the time to articulate it.

      Delete
  4. I also now realize this talk is over a year old......

    ReplyDelete