REST services are slowly becoming the norm. With the raise of SPA (Single Page Applications), REST API's have become the main way of consuming data.
These APIs are designed around resources. A resource can be an object, data, or service that can be accessed by the client. A resource has an identifier, which is a URI that uniquely identifies that resource. For example, the URI for a todo might be
https://todo.com/todos/1
Clients interact with a service by exchanging representations of resources.
Many web APIs use JSON as the exchange format. XML was used before, but now it's mostly JSON.
It makes use of HTTP verbs to perform operations on resources. The most common operations are GET, POST, PUT, PATCH, and DELETE.
API’s should be designed around resources
Let’s take an example of a TODO application. In this application, todo is a resource. If we need to create a todo, we will make a POST API call to https://todo.com/todos
API & the response status code will indicate the status of the action.
Resource URI naming
Resource URI’s should be based on nouns and not on actions. Use plural form of the resource.
Bad
https://todo.com/create-todo
Good
https://todo.com/todos
Resource Grouping
Let’s say our TODO app, allows users to group todo’s into a list. In that case the URI will look like this
https://todo.com/lists/{listId}/todos
From the URI you can see that, there is a hierarchy. In the above example we are addressing all the todos from the list {listId}
.
Addressing
Resources can be addressed individually with the resource id or all of them can be fetched at once when the id is not specified.
Fetch all TODO's
GET https://todo.com/todos
Fetch a specific TODO
GET https://todo.com/todos/1
Filtering
We have an API to get all TODO’s. Now, what if you want to fetch only the completed todo's ? This is where we use resource filtering.
GET https://todo.com/todos?status=complete
Resources can be filtered by using query string in the URI.
API operations
Here's is a table which describes the HTTP methods used and the description of when each one of them should be used.
HTTP Method | Description |
GET | Fetch one or all resources specified in the URI |
POST | Create a new resource |
PUT | Create or Update resource at the specified URI. PUT request must be idempotent |
PATCH | Partial update of the resource |
DELETE | Delete the specified resource |
Both POST & PUT can be used to create a resource. The difference being, when a resource is created using a POST request, the resource identifier is assigned by the server. But when a resource is created using a PUT request, the identifier provided in the URI will be used.
Resource ID will be assigned by the server
POST https://todo-app.com/todos
Resource ID 121
provided in the URI will be used
PUT https://todo-app.com/todos/121
The following table summarizes the common conventions adopted by most RESTful implementations using the todo example. Not all of these requests might be implemented—it depends on the specific scenario.
Resource | GET | POST | PUT | DELETE |
/todos | Retrieve all todos | Create a new todo | Bulk update of todos | Remove all todos |
/todos/1 | Retrieve the details for todo 1 | Error | Update the details of todo 1 if it exists | Remove todo 1 |
/todos/1/tasks | Retrieve all tasks for todo 1 | Create a new task for todo 1 | Bulk update of tasks for todo 1 | Remove all tasks for todo 1 |
Idempotent
An HTTP method is said to be idempotent if the same request can be made multiple times in a row resulting in the same effect. In other words, an idempotent method should not have any side-effects.
Let's take an example:
POST https://todo.com/todos
If you make this api call 10 times (with the same request body), then you would find 10 different resources in the server. This is because POST
is not idempotent and for every request it will create a new resource.
PUT https://todo.com/todos/121
In this case, no matter how many times the API is called (with the same request body), there will be only 1 resource and with the same data.
GET, PUT & DELETE are idempotent methods. Make sure that PUT
method is always idempotent.
Common Response status codes
The client determines the status of a request by looking at the response status code. Here are the most commonly used one's.
Code | Code String | Description |
200 | Ok | Request success |
202 | Accepted | Used for asynchronous operations |
204 | No Content | Delete success or no response body |
400 | Bad Request | Validation error |
401 | Unauthorized | User not logged in |
403 | Forbidden | User does not have access to the resource |
404 | Not Found | Resource not found |
404
is sometimes used when a user tries to access a forbidden resource. This is done, so that a malicious user doesn't figure out that a resource actually exists.
Data formats
xml
& json
are the 2 major data formats. In 2022 json
is the widely used format.
Stateless
REST API's should be stateless. Everything needed is within the request. Also the requests should be atomic. This enables web services to scale very well, as any server can take & process the request.
Summary
I hope this post has given you an overview of REST API Design. There is no fixed standard for REST, but there are commonly adopted guidelines and conventions.