REST API Design

Given the emergence of SPAs and mobile applications, usage of RESTful web services has never been more prevalent. Designing a beautiful one
takes time and usually involves many iterations. In this post, we will review relevant considerations for designing a RESTful API.

For example purposes, we will design a simple API around a messaging application. The goal of the API is as follows:

Create/Read/Update/Delete users

Create/Read/Update/Delete messages

Create/Read/Update/Delete comments for messages

Resources

The first step in designing your API is determining your resources. More specifically, the primary objects that define your data model. In this example, we have the following objects:

User

Message

Comment

URI

Now, we must determine the endpoints for these resources. This is arguably the most important part of the design process, since it’s the communication channel for consumers. Important factors to keep in mind during this are:

Use plurality if the object has many (/users vs. /user)

Endpoints should be named after their resource (/messages vs. /get-messages)

Objects that can’t exist on their own, don’t need their own endpoint (Comment can’t exist without Message)

Single objects (detail views) should live at the same root endpoint as their resource, but with their identifier appended

Given the above guidelines, we can shape our API as follows:

/users/

/users/:id/

/messages/

/messages/:id/

/messages/:id/comments/

/messages/:id/comments/:id/

Operations

Based on the goals we defined for our API, we have to allow for certain operations to be performed on our resources. Using standard HTTP request methods
, we can achieve all desired CRUD operations on our resources. Let’s break these down:

The ability to perform different operations on the same resource endpoint help keep your API simple and clean, thus avoiding messy, non-reusable endpoints, such as “/get-message-for-id/”.

Filtering / Sorting / Searching / Pagination

Of course, you’ll want the ability to query your resources, rather the same list, all of the time. The solution for this is simple, parameters. Simply accept different parameters, for different types of queries, at the appropriate list endpoints.

/messages/?archived=1 -> Filter messages for only archived

/messages/?sort=created_date -> Sort messages by created date

/messages/?q=django -> Search for messages containing “django”

/messages/?page=2 -> Return page 2 of X pages

While we just touched the base of API design, it should be enough to get started on the right foot. For next steps, we recommend checking out the API docs for some heavily used APIs (we recommend Stripe
and Dropbox
).