BT

Heroku’s HTTP API Design Guide

by Abel Avram on Aug 29, 2014 |

Wesley Beary, a member of the API team at Heroku, has compiled a list of guidelines for creating HTTP+JSON APIs presented in a condensed form here.

The guide starts with a number of general recommendations:

  • Require all API calls to use TLS. Reply with 403 Forbidden to non-TLS ones
  • Always version an API. Use the Accept header to specify the version. Require clients to specify the API version instead of relying on a default one
  • Use the ETag header to support caching of resources
  • Identify each response with X-Request-ID; useful for logging or debugging purposes
  • Use Range, Content-Range, Next-Range to deal with large responses

For making requests, the guide mentions:

  • Return appropriate status codes, such as:
    200: Successful GET or synchronous DELETE, PATCH
    201: Successful synchronous POST

    401: Unauthorized call
    429: Too Many Requests
    etc.
  • Return complete resources when available
  • Accept serialized JSON in requests for symmetry with JSON responses
  • Use consistent path formats. Resource names should use the plural form unless they refer to singletons
  • Use lowercasing for paths and attributes to keep in line with host names
  • Allow some resources, such as application names, to be specified by their name besides UUID
  • Try to limit the depth of resource nesting by allocating them closer to the root path

When it comes to responses, Beary suggests:

  • Use globally unique IDs for each resource
  • Provide standard timestamps for resources
  • For timestamps, use UTC in format ISO8601
  • Nest foreign key relations to be able to include more details for the related resource without changing the structure of the response
  • Provide detailed errors, including a machine readable ID, a human readable error message and an optional URL pointing to more details
  • Establish a request rate limit and inform the client on the number of available request tokens with each response, using a header like RateLimit-Remaining
  • JSON should be minified in all responses

The guide includes more related advice:

  • Provide the JSON schema in a machine readable format
  • Include detailed APIs documentation for developers
  • Allow developers to test the APIs
  • APIs should be marked according to their stability status: prototype/development/production

We asked Beary how they came up with these guidelines and to explain some of them.

InfoQ: Have you had a guide from the beginning?

WB: I had some portions of the guide from early on, but they were pretty rough and lived only in my head. From my work on github.com/fog/fog and related things I had consumed many different APIs, which went a long way toward informing my opinions.

InfoQ: If you did not have the guide from the beginning, how did you develop the API? Through iterations?

WB: Lacking a more formal guide, it was definitely a process of iteration. Unfortunately, in addition to being somewhat slow, the iteration process was not scalable. It left me as a roadblock to adding new things. We built the guide to help distribute that decision making. We continue to iterate, but often it is now also on the guide itself. There are many ongoing discussions (github.com/interagent/http-api-design/issues) which continue to clarify and evolve the document as we learn more and other developers adopt it.

InfoQ: Why is it recommended to return the whole resource on a PUT or DELETE operation?

WB: Exceptional cases are the enemy in interfaces and guidelines. Sometimes the whole resource will be desired and leaving it out is mostly an optimization. I think having this as optional, opt-in behavior could make good sense in many cases, but having an easy, usable default is valuable. That said, this is a contentious point and there is some ongoing, deeper discussion about the pros and cons at https://github.com/interagent/http-api-design/issues/9.

InfoQ: Why using only UTC times formatted in ISO8601?

WB: Similar to returning the whole resource, having a consistent rule (without exceptions) makes it easier to reason about what you are doing and reduces the number of decisions you have to make when designing something. Also, time zones are crazy and terrible. I have lost count of the number of timezone related errors I have encountered and caused. In order to hopefully reduce the issues, we chose a known timezone and format to use throughout.

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

REST? by Jean-Jacques Dubray

It's great to see that we are slowly dropping the REST qualifier and come back to our senses towards HTTP+JSON APIs.

For sure, there were interesting lessons to learn from REST, which this guidance captures well, but in the end Bookmarks/Hypermedia, the "Uniform" Interface, Schemaless interface definitions or even Resource Orientation simply made no sense outside a browser.

It only took about 7 years to land back on our feet, but indeed, we did.

Re: REST? by Carlos Mendonça

I wondering what's missing from formats such as OData that prompts people to reinvent the wheel over and over again.

Re: REST? by Jean-Jacques Dubray

the OData spec is 68 pages long.

Re: REST? by Carlos Mendonça

Nothing is stopping ppl from doing a partial implementation (which I have seen often, btw).

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

4 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT