What’s a (Good) REST API?

This article was published 1 year, 1 month ago. Due to the rapidly evolving nature of web development, some concepts may no longer be applicable.

Recently, a colleague who is a front-end developer asked me what the qualities were for a good REST API. He had been experimenting with AngularJS and wanted to get a rough idea of whether or not he could expect the resource objects returned by Angular’s $resource factory to work nicely with them.

Strangely, this was a question hard to pin down an answer for. I’ve worked with RESTful APIs for years and had a good idea what made a good REST API (“I know one when I see it”), but never really given much thought to it. Roy Fielding first defined REST in his doctoral dissertation back in 2000, but that tome was a lot thicker than the quick bullet-points my colleague was looking for.

RESTfulness is something that happens in degrees. I think I might classify it thusly:

Not RESTful, even though the API creators might claim that it’s RESTful

These alone don’t make an API RESTful:

  • Uses HTTP or HTTPS
  • Returns XML and/or JSON

Occasionally you’ll run into some misguided folks who think that the above two points are all it takes to slap the REST seal-of-approval on their APIs. Ironically, REST pedants will tell you that specifying the protocol or format not only is inadequate qualification for RESTfulness, but it actually runs afoul of the spirit of REST.

Warning signs that a self-proclaimed REST interface that isn’t:

  • Verbs are in your URL (e.g., http://example.com/reservation/get or http://example.com/business/search)
  • You are using POSTDATA to send query parameters even though you aren’t changing the server’s application state.

Mostly RESTful

A mostly (and I’d claim adequately) RESTful interface has these qualities:

  • Uses URLs to refer to resources. These resources are the “nouns” in the system. Examples of a resource might be an account, a transaction, a user, an appointment, etc.
  • Uses the four best-known, well-recognized “HTTP Verbs”, and defines them semantically to mean the following “CRUD” operations:
    • GET – read a resource or list of resources
    • POST – create a new resource
    • PUT – modify an existing resource
    • DELETE – delete a resource
  • You might wonder how you actually *do* something like, e.g., a payment, in a system designed so noun-centrically like this. It seems actions/verbs have no place in it. However, even in these cases you are creating a transaction. So you’d POST/create a payment resource. Everything is expressed in terms of resource lifecycle events.
  • Uses semantically appropriate error codes. E.g., 404 means the resource isn’t found. A 401 means you aren’t authorized to view it. A 422 means something about the data or request was malformed.

Hardcore RESTful / Hypermedia

The highest degree of RESTful APIs I’ll refer to as “Hardcore RESTful.” They have the following qualities:

  • Doesn’t necessarily define a protocol/transport (e.g., HTTP). As I said above, pedantic REST nerds will tell you that restricting REST to a single protocol violates the spirit of REST. The reality is that REST almost always implies HTTP.
  • Doesn’t define something like a version number in the URL – a version isn’t semantically a resource or a part of the resource. Instead API versioning can be done using something like HTTP header values (e.g., Accept:), or some other side-band portion of the protocol.
  • Similarly, it shouldn’t define a desired data format in the URL (http://host.com/foo.json), and should instead do that via some side-band part of the protocol like HTTP headers (e.g., content Accept:). You can embed versioning and desired format in a MIME type that is passed as an Accept header like this: application/vnd.mycompany.myapp-v1+json
  • To take a RESTful interface up to the next level, you can create an API that builds upon REST and does not return hierarchical data. Instead it returns URLs to subsets of data. This style of API is usually referred to as a “Hypermedia API” for its reliance on hyperlinks. E.g.,

BAD

<account>
  <name>Checking</name>
  <balance>100.00</balance>
  <user>
    <name>Elvis Presley</name>
    <address>Graceland</address>
    <city>Memphis</city>
    <state>TN</state>
  </user>
</account>

GOOD

<account>
  <name>Checking</name>
  <balance>100.00</balance>
  <user href="http://example.com/user/elvis-presley"/>
</account>

The argument for this style of design are that your inner URLs can change at a later date, and not break the entire API. It also enables “discovery” of the interface by allowing a client to start at a root node of the API, following links much like a search-engine spider or bot would. This also engenders systems to evolve their APIs independently -theoretically, a client with a generic ability to interpret hypermedia shouldn’t get tripped up by a less rigid definition of the API. Proponents of Hypermedia APIs often speak of a concept called “Hypermedia as the Engine of Application State“, or HATEOAS for short.

Arguments against this style is that, in practice, this manner of API discoverability is of limited usefulness and actually incurs an overhead by requiring more API calls than would be otherwise needed.

In Summary

What I told my colleague was this: most REST APIs out there meet the “mostly RESTful” level of compliance. Given that, most REST client abstractions will probably work OK if the API is at least at that degree of RESTfulness (with the caveat that I didn’t wade very deeply into Angular’s resource library!). If you’re creating a brand new REST API, it’s good to aim a little higher than that – you’re clients will appreciate it.

If you want to read more about REST and Hypermedia APIs, Steve Klabnik has written an excellent series of blog posts  which expand on these ideas a whole lot more.

11 Responses to “What’s a (Good) REST API?”

  1. Pingback: Dew Drop – July 15, 2013 (#1,585) | Alvin Ashcraft's Morning Dew

  2. Jon Davis

    I believe in the mixed bag of nested hierarchical data as summaries with entity identifiers. In other words, (replacing less-than with ‘[' and greater-than with ']‘ because your comments system doesn’t indicate support for code)

    [account]
    [name]Checking[/name]
    [balance]100.00[/balance]
    [user href="http://example.com/user/elvis-presley"/]
    [name]Elvis Presley[/name]
    [address]Graceland[/address]
    [city]Memphis[/city]
    [state]TN[/state]
    [/user]
    [/account]

    The reason I prefer this is because it summarizes the user entity, not divulging much, but providing just enough to describe in human terms who the person is either for human readability and possible “good enough” validation alignment. Having the URI there for a data subset lookup would be useful if the provided subset summary is insufficient and a detailed lookup is required; otherwise, having the summary there would reduce the likelihood of the necessity of the lookup. It’s the same argument for denormalization for the sake of performance and administrative convenience, in SQL / RDBMS.

  3. Massimo Luise

    I thought POST wat for update a resource, while PUT was for create a new resource…

  4. Damien Cattorini

    According to the HTTP/1.1 RFC (http://tools.ietf.org/html/rfc2616), POST and PUT both can be used to CREATE or UPDATE.

    PUT = Store the enclosed entity under the supplied Request-URI
    If the resource identified by the Request-URI doesn’t exist yet, this resource is created. Otherwise, this resource is replaced.

    POST = Store the enclosed entity (which may be processed by the server) as a new subordinate of the resource identified by the Request-URI
    So it may create a “sub-resource” or update an existing one.

    One does not simply map CRUD operations with HTTP verbs.

    Moreover, if you want to do specific changes on a resource, there’s also the PATCH HTTP verb (http://tools.ietf.org/html/rfc5789), which can also be mapped to CREATE (if the server can logically modify a null resource) or UPDATE operations

  5. Pingback: The rest API maturity model explained quite neatly | Mikado Software

  6. John Munsch

    My concern with referring to individual resources as URLs is that it tends to suggest to people that they’re going to perform multiple calls to do something which needs to be transactional. If you find yourself making one call to take money out of an account and another to add that money to another account then your API is poorly designed whether it’s “REST” or not.

    I think I’ll do a follow up on this on my own website soon.

  7. Pingback: Yes it’s “REST” but is it any good? | JohnMunsch.com

  8. Tyler Hallada

    I’m a REST noob wading in a sea of acronyms and overly verbose wikipedia articles; this is the only thing I’ve read so far that put everything together into something that made sense.

    Cheers.

  9. http://www.gamesebooks.com/ultimate-mma-strength/sitemap/76

    The way that these foods act with your body will reset itself.
    Crash dieting quotes has become such a common phenomenon that we
    think that it is the best way to get the body of their dreams.
    Juicers are expensive The skin and the pulp of fruits and vegetables, which isn’t true. Don’t
    be Lazy it is better to avoid alcohol consumption when dieting quotes if
    you can collect the bruised or substandard fruits and vegetables when consumed properly.

    They seem good at first, but they adversely stimulate the body’s survival mechanisms.