How To Design Practical RESTful API

There are lots of posts on the Internet on how to design RESTful API already, so why to bother with writing another one? Unfortunately many posts are rather theoretical. They carelessly mix important and unimportant for practice stuff together, sometimes flavouring the mix with questionable recommendations.

It's not easy to find a good practical article on the topic, and Best Practices for Designing a Pragmatic RESTful API by Vinay Sahni is one of these rare pearls. Vinay's post is a comprehensive lengthy chunk and, if you have time, I highly recommend it. If you are after a shorter summary of the most important issues that developers face on daily basis, read on.

Why designing API is important?

Believe it or not, RESTful API is a user interface for developers. What does it imply? First and foremost, quality of API determines its success. Nobody will use shitty API if there is a better alternative.

If you design API for internal consumption within enterprise, other developers will have to consume it, but they won't be happy and will secretly (or openly) hate you if you make it awkward.

URLs

URLs represent the essence of RESTful API and raise a bunch of questions.

Plural or single?

The most common practice is to use plurals. E.g., a bookstore service could have books/ endpoint. But don't rush to convert singles to plurals when you join a project where singles are used. Consistency is more important.

Beyond CRUD, how to represent actions?

REST clearly says that for CRUD (create/read/update/delete) operations you must leverage existing HTTP methods (POST/GET/PUT/DELETE). Unfortunately it's not as clear what to do with actions.

There are three different ways how actions are implemented in practice:

  • Subresource, e.g. books/12345/buy
  • Parameter, e.g. books/12345?action=buy
  • Root action, e.g. search/author=Aho&name=Compilers

Subresource is usually perferred if you need to make an action on a single resource, e.g. to buy a book with specified ISBN. Root action is ubiquitous for search operations.

HTTP status codes

HTTP protocol includes a plethora of status codes. Below are status codes that you will often find in RESTful API grouped by HTTP method.

Method-agnostic
  • 401 Unauthorized - User is not authenticated.
  • 403 Forbidden - User is authenticated, but not authorised to have access to the resource.
  • 404 Not Found - Resource does not exist.

Note that names of status codes 401 and 403 are really misleading.

GET
  • 200 OK - Resource was found and returned in body.
POST
  • 200 OK - Resource was created and returned in body.
  • 201 Created - Resource was created and Location header of response points to it. Body should be empty.
  • 400 Bad Request - Request is malformed, e.g. the body does not parse.
  • 415 Unsupported Media Type - Media type of request (e.g. "application/xml") is not supported by service.
  • 422 Unprocessable Entity - Body doesn't pass validation.
PUT
  • 204 No Content - Resource was updated and body is empty.
  • 400 Bad Request - Request is malformed, e.g. the body does not parse.
  • 415 Unsupported Media Type - Media type of request (e.g. "application/xml") is not supported by service.
  • 422 Unprocessable Entity - Body doesn't pass validation.
DELETE
  • 204 No Content - Resource deleted and body is empty.

And JSON for all

JSON is a de facto standard for data transmission nowadays. It's a no brainer that JSON should be used for data transfer. But what some API designers miss - errors should be passed in JSON too. This unifies transmission format and simplifies handling responses by your service clients.

HTTP or HTTPS?

For all services exposed outside (of your company) you must use HTTPS. Period. Occasionally it could be acceptable to use HTTP for internal services, but there must be really good reasons for doing that.

In Summary

When you design RESTful API, do your best to make it simple, consistent and convenient, as you usually do when designing user interface. Follow standards when it makes sense, but prefer simple practical solutions over awkward theoretical ones if required.

comments powered by Disqus