REST API Design Cheat Sheet

5 months 2 weeks ago

Good restful API design is very difficult process. An API represents a contract between you and those who consume your data. Building an API is one of the most important things you can do to increase the value of your service. By having an API, your service / core application has the potential to become a platform from which other services grow. Look at the current huge tech companies: Facebook, Twitter, Google, GitHub, Amazon, Netflix… None of them would be nearly as big as they are today if they hadn’t opened up their data via API. In fact, an entire industry exists with the sole purpose of consuming data provided by said platforms. The easier your API is to consume, the more people that will consume it. This article is very helpful when designing your API and this will that Consumers of your API will be able to understand what is going on, and should drastically reduce the number of confused. Here’s a few of the important terms I will use throughout the course of this document:

  • Resource: A single instance of an object. For example, an animal.
  • Collection: A collection of homogeneous objects. For example, animals.
  • HTTP: A protocol for communicating over a network.
  • Consumer: A client computer application capable of making HTTP requests.
  • Third Party Developer: A developer not a part of your project but who wishes to consume your data.
  • Server: An HTTP server/application accessible from a Consumer over a network.
  • Endpoint: An API URL on a Server which represents either a Resource or an entire Collection.
  • Idempotent: Side-effect free, can happen multiple times without penalty.
  • URL Segment: A slash-separated piece of information in the URL.

Resource naming

  • Use nouns as resource names - like "products", "users", etc. (don’t use verbs in URLs)
  • plural form - more descriptive and consistent than the singular form, never use both in the same API

Use the Collection Metaphor

  • Two URLs (endpoints) per resource:
    • The resource collection (e.g. /reviews)
    • Individual resource within the collection (e.g. /reviews/{reviewId}).
  • Use plural forms (‘reviews’ instead of ‘review’).
  • Alternate resource names with IDs as URL nodes (e.g. /reviews/{reviewId}/companies/{companyId})
  • Keep URLs as short as possible. Preferably, no more-than three nodes per URL.

Resource representations

  • “No Naked IDs!” No plain IDs embedded in responses. Use links and reference objects.
  • Design resource representations. Don’t simply represent database tables.
  • Merge representations. Don’t expose relationship tables as two IDs.
  • Use ISO 8601 timepoint formats for dates in representations.(ex: Date: Sun, 06 Nov 1994 08:49:37 GMT)

Methods and response status codes

GET /resource

  • Returns the whole resource (or filtered) collection
  • Status codes - 200 (OK), 400 (invalid query params)

GET /resource/{id}

  • Returns a single record
  • Status codes - 200, 404

POST /resource

  • Create and other non-idempotent operations
  • Returns the created record with its ID
  • Status codes - 201 (Created), 400 (data validation error)

PUT /resource/{id}

  • Update existing resource
  • Returns the modified record
  • Status codes - 200, 404, 400, 301 (moved permanently in case of ID change)

DELETE /resource/{id}

  • Remove a resource or collection
  • Status codes - 204, 404

Ensure that your GET, PUT, and DELETE operations are all idempotent. There should be no adverse side affects from operations.

Meaningful HTTP status codes

  • 200 - Success.
  • 201 - Created. Returned on successful creation of a new resource. Include a 'Location' header with a link to the newly-created resource.
  • 400 - Bad request. Data issues such as invalid JSON, etc.
  • 404 - Not found. Resource not found on GET.
  • 409 - Conflict. Duplicate data or invalid data state would occur.

Use Content-Type negotiation to describe incoming request payloads

For example, let's say you're doing ratings, including a thumbs-up/thumbs-down and five-star rating. You have one route to create a rating: POST /ratings How do you distinguish the incoming data to the service so it can determine which rating type it is: thumbs-up or five star? The temptation is to create one route for each rating type: POST /ratings/five_star and POST /ratings/thumbs_up However, by using Content-Type negotiation we can use our same POST /ratings route for both types. By setting the Content-Type header on the request to something like Content-Type: application/vnd.company.rating.thumbsup or Content-Type: application/vnd.company.rating.fivestar the server can determine how to process the incoming rating data.

Consider Cache-ability. At a minimum, use the following response headers:

  • ETag - An arbitrary string for the version of a representation. Make sure to include the media type in the hash value, because that makes a different representation. (ex: ETag: "686897696a7c876b7e")
  • Date - Date and time the response was returned (in RFC1123 format). (ex: Date: Sun, 06 Nov 1994 08:49:37 GMT)
  • Cache-Control - The maximum number of seconds (max age) a response can be cached. However, if caching is not supported for the response, then no-cache is the value. (ex: Cache-Control: 360 or Cache-Control: no-cache)
  • Expires - If max age is given, contains the timestamp (in RFC1123 format) for when the response expires, which is the value of Date (e.g. now) plus max age. If caching is not supported for the response, this header is not present. (ex: Expires: Sun, 06 Nov 1994 08:49:37 GMT)
  • Pragma - When Cache-Control is 'no-cache' this header is also set to 'no-cache'. Otherwise, it is not present. (ex: Pragma: no-cache)
  • Last-Modified - The timestamp that the resource itself was modified last (in RFC1123 format). (ex: Last-Modified: Sun, 06 Nov 1994 08:49:37 GMT)

Support filtering, sorting, and pagination on collections

Shahid Hussain

Shahid Hussain is a frontend developer and UX Consultant living and working in Sweden. Shahid is specializes in JavaScript development and developed anything from WordPress websites to complex e-commerce JavaScript applications. Shahid can also sketch, from websites to apps and icons, even print material. He works on content-centric, and mobile products, as well as cross-portal user experiences. Photography, music and travelling can trigger his attention.