Yet another REST cheat sheet

I believe that good interfaces are even more important than good code. When refactoring a bad interface, code behind (providers) that interface and code before (consumers) that interface has to be refactored (not to forget the interface itself). Weighting even more heavily the more systems use the bad interface. When refactoring bad code behind a good interface or before a good interface, everything else stays untouched.

I observed that many developers, even the very experience ones, don’t seem to care too much on interfaces, doing them on the fly, thereby creating a technical debt for the future and causing many pains being hard or impossible to get rid of again …

While working on microservices I was doing some research on how to design RESTful interfaces. For doing good API design (in terms of library) you are focusing on the possible use cases, taking care of decoupling, regarding the Law of Demeter and more the such. In addition you require some sound experience in doing good API design.

Designing RESTful interfaces is somehow different to API design as the former focuses on resources and domains and the latter focuses on functionality, transactions or the such.

The rules on RESTful interface design fit on a single page; though when you take them seriously, following the idea of everything being a resources, then you end up with astoundingly robust and extensible (non-breaking) interfaces.

Below find an except from resources such as Using HTTP-Methods for RESTful Services from which I distilled what I consider helpful when designing your robust end extensible RESTful services:

Locators

Yes, the basics are just about your resources being collections and elements which your service provides using locators to address your resources. The art of building a RESTful service is to arrange your collections and elements in a locator’s path to represent your domains in question. Let’s formalize the process of creating your locators:

Creating good RESTful interfaces is much easier than creating a good API as creating RESTful interfaces can be formalized!

Break down your domain into a tree representing a hierarchical structure of your domain. Let’s call this hierarchical structure your domain resource hierarchy. To address a resource in this domain resource hierarchy you use a locator which points to that very resource.

Let’s take a look at a banking account service and let us break down this banking domain into a domain resource hierarchy and see which locators magically jump out of the nowhere.

Given the online bank acme.com has customers whom have bank accounts, money transactions may be applied on such a bank account and so forth. The hierarchical structure for this business case ends up in this banking domain resource hierarchy:

The schema for the path or locator pointing to an individual transaction distills as follows:

customers<customer_id>accounts<account_id>transactions<transaction_id>

Given a customer with the customer_id=d having an account with account_id=3 on which a transaction with transanction_id=5161has been applied, locators till the transaction 5161 for a RESTful service look like this:

  1. https://acme.com/customers/d
  2. https://acme.com/customers/d/accounts/
  3. https://acme.com/customers/d/accounts/3
  4. https://acme.com/customers/d/accounts/3/transactions/
  5. https://acme.com/customers/d/accounts/3/transactions/5161

As REST is all about collections and elements the above locators read as follows:

  1. Address the customer d element
  2. Address a collection of all accounts for customer d
  3. Address the account 3 element of customer d
  4. Address a collection of all transactions for account 3 of customer d
  5. Address the transaction 5161 element for account 3 of customer d

Methods

The HTTP methods GET, PUT, POST and DELETE of RESTful services distinguish between single collections and elements:

  • Collection: E.g. http://acme.com/resources
  • Element: E.g. http://acme.com/resources/item17
Method Collection Element
GET 200 OK, list the URIs and perhaps other details of the collection’s members. Use pagination, sorting and filtering to navigate big lists. 200 OK, retrieve a representation of the addressed member of the collection, expressed in an appropriate Internet media type. 404 Not Found, if ID not found or invalid.
PUT 404 Not Found, unless you want to update/replace every element in the entire collection: Then replace the entire collection with another collection. 200 OK or 204 No Content, replace (update) the addressed member of the collection, or if it doesn’t exist, create it. 404 Not Found, if ID not found or invalid.
POST 201 Created, create a new entry in the collection. The new entry’s URI is assigned automatically and is usually returned by the operation. Location header with link to the new element. 404 Not Found, not generally used. When supported, then treat the addressed member as a collection in its own right and create a new entry in it.
DELETE 404 Not Found, unless you want to delete the whole collection - not often desirable: If so, then delete the entire collection. 200 OK, delete the addressed member of the collection. 404 Not Found, if ID not found or invalid.

Sessions

In case you really, really, really need something like a server side state for a user, be it of security reasons or other constraints, think about handling such server side session information as a separate resource.

Some inspirations on sessions flying around out there on the internet:

  • Establish a session token via a POST or by using an API key as a POST body argument or as a cookie.
  • Usernames, passwords, session tokens, and API keys do not appear in the URL, as this can be captured in web server logs, which makes them intrinsically valuable.
  • Use only the session token or API key to maintain client state in a server-side cache (no state blob being sent as part of the transaction).

Response codes and error handling

Applicable HTTP response codes for the HTTP methods regarding collections and elements:

Response Code GET PUT POST DELETE
200 OK Collection, Element Element n/a Element
201 Created n/a n/a Collection n/a
204 No Content n/a Element n/a n/a
404 Not Found Element Element, Collection Element Collection

HATEOAS

“… Hypermedia as the Engine of Application State, kurz HATEOAS, ist ein Entwurfsprinzip von REST-Architekturen. Bei HATEOAS navigiert der Client einer REST-Schnittstelle ausschließlich über URLs, welche vom Server bereitgestellt werden…” (HATEOAS)

REST Maturity Model

“… Das REST Maturity Model (REST-Reifegradmodell), kurz RMM, ist ein von Leonard Richardson entwickelter Maßstab, der angibt, wie strikt ein Service REST implementier…” (REST Maturity Model)

The REST Maturity Model defines how RESTful a REST service actually is:

Level HTTP-Methods URIs/Resources Protocol
0 One (often POST) Single URI XML-RPC, SOAP
1 One (often POST) Multiple web resources ROA
2 GET, PUT, POST, DELETE Multiple web resources ROA
3 GET, PUT, POST, DELETE Multiple web resources ROA alongside HATEOAS/HAL using hypermedia for navigation

Useful query parameters

Working on collections means that you might want to get just those elements of interest, be it as of performance reasons or as of business logic requirements. Below find some according useful query parameters:

Purpose Parameters
Pagination ?offset=x&limit=y
Sorting sort=<criteria>&order=[ASC|DESC]
Max results ?max=n
Dedicated elements ?id=xyz&id=abc&id=def&...

Further reading