A Practical Introduction to REST API Design

For someone who’s creating web-apps for the first time in their life, the typical tutorial on REST can be confusing. There is a lot of theory that might be difficult to understand. This tutorial aims to do the opposite. It starts with the practical application and examples, and skips the theory. There will be links to other articles towards the end, which explain the theory in detail.

Who is this for?

This tutorial is aimed towards beginners who are starting to learn web-development, and are trying to understand what are REST APIs and how to design them, or have started creating REST APIs and are trying to learn how to better design REST APIs.

Client-Server Communication

Let’s consider Gmail. When you first open your email, the server sends back 2 types of information —

  1. The Data — The list of emails and their details such as author, subject, snippet, date.
  2. The Presentation — HTML, CSS, Javascript used to render this list of emails

When you click Refresh, the website wants to do it as soon as possible so you have a good user experience. Therefore it will try not sending the presentation information again. It will only request for the data once again.

This can be achieved using APIs in any format that the client and server agree to, over whatever protocol they agree to.

REST is an architectural style that helps create APIs that are simple and powerful.

Basic Components

The REST Architecture uses the HTTP protocol. There are 4 basic components that make up an HTTP request. REST defines how to use these to create powerful APIs.

  1. URL: This is the URL we send the request to. For example, https://<mywebsite.com>/users
  2. Method: All HTTP requests contain a method. When you type a URL into a browser, the method used by default is GET. The most commonly used HTTP verbs (methods) are GET (retrieve), POST (create), PUT (update), DELETE (delete).
  3. Body: An HTTP request can contain a body. This is typically used to send content, for example the username/password during login, or the user’s profile information when creating / updating the user.
  4. Query Parameters: When you search for something on Google/Bing, you will see this in the URL — /search?q=rest . Here q=rest is a query parameter, where q is the key and rest is the value.

A Practical Example

Instead of going over the principles of REST, we’ll try to understand it be relating it to Object Oriented Programming.

We’ll take a list, and see the various operations we can perform with it — retrieve, add, delete, update, and explain how to convert all of this into meaningful REST APIs.

While this tutorial is useful if you just read it, hands-on practice will add even more value. To make best use of this tutorial, install Postman on your laptop, and actually make the requests along with us. This tutorial will be using dummy APIs provided by websites just for the purpose of testing.

Rule Number 1

Assume you have a list of users.

In Java/Kotlin, to return all the users, you would probably say —

return users

In REST, this translates to —

GET <mywebsite>/users/

This leads us to rule number 1.

Rule number 1 —

When creating REST APIs for a collection of items, limit the URL to just the collection name, and mention the action in the verb (method).

Notice that we don’t say /users/all or /getUsers/all or /users/getAll . The method is already a verb, and the URL just needs to mention the resource.

Exercise: Use postman to send a get request to retrieve all users and verify that you get a successful response as shown below.

Rule Number 2

To create a new user, in Java/Kotlin we would say —

users.add(newUser)

In REST this would translate to —

Method: POST 
URL: /users/
Body: {"name": "John Brown", "occupation": "Carpenter"}
Header: Content-Type: application/json

Any parameters to the method translate to the body in REST. We need a header to specify the type of content. This leads us to rules number 2.

Rule number 2 —

Any data that needs to be sent to the request goes as the body, with a header Content-Type that defines the format of the body (JSON/XML etc).

Exercise: Use Postman to make a POST request to https://reqres.in/api/users and verify that the response contains the user object along with its id.

Rule Number 3

Think of how you’d retrieve the user which has the ID 17 in from a list? Using Kotlin’s clean syntax we can write —

return users.single { it.userId == 17 }

Ideally, what we’re trying to say is users.findById(:userId) , except that the syntax is not as concise.

In REST this would translate to —

Method: GET 
URL: /users/17

A more generic syntax for this would be

Method: GET 
URL: /users/:userId

Here userId is the unique identifier, and could be anything, even a name, or a commit SHA.

Another example is the following —

Method: DELETE
URL: /users/:userId

You can understand how concise and expressive REST is! I hope I don’t have to explain what happens above. We’re deleting the user with a particular user id.

This brings us to Rule Number 3 —

Within a collection, access a particular element by its unique identifier. Use the method to define what needs to be done with it.

Exercise: Use Postman to GET, update (using PUT), and DELETE a particular user. If you’re confused, you can refer to the screenshots below and copy what we’ve done.

Rule Number 4 —

A more complex example of what we’re doing above would be the following —

articles.findById(:articleId).comments.findById(:commentId)

This would translate to —

articles/:articleId/comments/:commentIdExample: articles/17/comments/88

This gets us to rule number 4 —

Sub-collections are denoted by relative paths in queries. 

Here’ comments are a sub-collection of an article.

Exercise: Navigate to the GMail API page. On the right hand pane, enter your gmail address as the user id, and see how their nested request works.

Rule Number 5 —

What if you want to filter users that have exactly zero points, or get only users that are active?

return users.find { it.points == 0 } 

It is not content we have to provide the server, so we don’t want to use the body. This doesn’t fit well as a part of the url either.

This can be solved by doing the following —

Method: GET
URL: /users?points=0&active=true

When you have situations where you have to provide parameters that are either optional, or don’t fit in the query string as a subset of a particular type, we can pass them as query parameters. This also includes search queries, or page numbers.

This can be formalised as Rule number 5 —

Additional information needed to process a request to retrieve information that is not a sub-collection goes as a query parameter. 

Exercise: Navigate to the GMail API page that we used in the previous exercise. Try adding a search query parameter.

Putting it all together —

We have the following rules —

  1. When creating REST APIs for a collection of items, limit the URL to just the collection name, and mention the action in the verb (method). This action includes GET (retrieve), POST (create), DELETE (delete), PUT (update).
  2. Any data or content that needs to be sent as a part of the request goes as the body, with a header Content-Type that defines the format of the body (JSON/XML etc).
  3. Within a collection, access a particular element by its unique identifier such as id or name.
  4. Sub-collections are denoted by relative paths in queries.
  5. Additional information needed to process a request to retrieve information that is not a sub-collection goes as a query parameter.

Bonus Rule: Feel free to move away from these rules if they help simplify the url.

Exercise: Try navigating to a commit on github. See the collections that we have to navigate —organisations, repositories, and commits. But they don’t mention all 3 in the URL. See how they’ve broken some of these rules to make the URL concise.

What Next?

Now that you have a practical framework to think about REST APIs, I would recommend diving into the theory. There are many elements I’ve not mentioned here, which influence some of the rules I’ve come up with above. There are also other aspects to REST, such as dealing with authentication and why choose certain practices over the other. I would recommend reading about those too.

Further Reading

Educator, Founder @ Interleap