Backend Basics #4
Complete REST API Design
Also check out Production Ready REST APIs in a Monolithic Architecture for more details on REST API design and principles.
REST principles
- Client Server Model
- Uniform Inference
- Layered System
- Cache
- Statelessness
- Code on Demand
Core REST vocabulary
| Term | Meaning |
|---|---|
| Representational | Resources on the web are specified in various formats, example JSON, xml, HTML, etc. |
| State | Current condition / attribute of the resource |
| Transfer | movement of resource representation between the client and server |
REST format state representations scalable
Resource naming
https:/api.example.com/v1/books
resources should be plural ^
https:/api.example.com/v1/books/:id
fetching a single book ^
never put capital, underscore and spaces in a url
Harry Potter -> harry potter -> harry-potter
make slug
Idempotency
Performing an action multiple times has the same effect as it is performed once
POST is the only method which is non Idempotent because a resource is created and the effect is different
POST is open ended
when there is a custom action which cannot be segregated into other methods, we use the POST method
example - /send-email
Designing
Follow proper standards and best practices
- Start with UI design interface and follow the wireframe - you have an idea how the users will interact with the data.
- Resources are the nouns you can find, example - projects, users, organizations, tasks, tags, etc.
- Then you design the DB Schema
Organization {
id: string;
name: string;
status: "active" | "archived";
description?: string;
createdAt: string;
updatedAt: string;
}
Project {
id: string;
name: string;
organizationId: string;
status: "planned" | "in-progress" | "completed";
description?: string;
createdAt: string;
updatedAt: string;
}
Task {
title: string;
projectId: string;
status: "pending" | "in-progress" | "completed";
priority: "low" | "medium" | "high";
assignedTo?: string;
assignedAt?: string;
description?: string;
createdAt: string;
updatedAt: string;
}
- Then work on API Design
list out all the actions that users will take - CRUD
Then use insomnia or postman to design the API
Pagination
Pagination is a server side technique where a list of some kind of resource is returned, it only returns a particular portion of resources and not all resources at once if there is a lot of data.
Example response
{
"data": [
{
"id": "dd352e4j7",
"createdAt": "2025-02-08T12:15:41.512Z",
"name": "Org1",
"status": "active",
"description": "some descr"
}
],
"total": 1,
"page": 1,
"totalPages": 1
}
total returns the total count of resources for representational purposes
page = which portion of data which we are asking from the server
totalPages - how many pages in total there are
if page = totalpages, end of page
Query parameters
Server takes 2 query parameters for how pagination works
first is limit
second is page
by default limit is like 10-20 and page is 1
GET http://localhost:3000/organizations?limit=2&page=1
Response (200 OK):
{
"data": [
{
"id": "2yrxx4hn",
"createdAt": "2025-02-08T12:15:41.752Z",
"name": "Org5",
"status": "active",
"description": "some descr"
},
{
"id": "1keyj7m",
"createdAt": "2025-02-08T12:15:41.352Z",
"name": "Org4",
"status": "active",
"description": "some descr"
}
],
"total": 5,
"page": 1,
"totalPages": 3
}
Sorting
Server should also support sorting
this takes 2 parameters
sortBy - name
sortOrder - asc
server should set sane default values so that the user shouldn't send obvious entries, example - page number
default natural sorting -
createdAt
desc
Filtration functionality
take status parameter
PATCH
Mostly use PATCH instead of PUT when updating partial fields of a resource
https://api.example.com/organizations/:id
req body sent with PATCH -
{
"status": "active"
}
This changes only the status
Custom actions
Custom actions such as archiving
are put under POST request
They do not fall under traditional crud
Send a POST request
https://api.example.com/organizations/:id/custom-action
this post call will change the status to ARCHIVED
this will return 200 OK
| Method | Endpoint | Action |
|---|---|---|
| POST | /organizations | Create Org |
| GET | /organizations | List Orgs |
| GET | /organizations/:id | Get Org |
| PATCH | /organizations/:id | Update Org |
| DELETE | /organizations/:id | Delete Org |
| POST | /organizations/:id/archive | Archive Org |
Always make keys similar and do not rename fields in json data
example "description" shouldn't be changed to "desc"
be consistent in making APIs
For projects, copy / clone is a new custom action
https://api.example.com/projects/:id/clone
response code might change and server might send a 201 response since something is being created
Things to keep in mind when making APIs
- Interactive Documentation - Start using swagger api to start documenting things, how frequently you maintain your API
- Keep things intuitive and consistent - Follow standards and do not change your patterns
- Provide Sane defaults - If nothing is passed by the client, there is a default fallback
- Avoid abbrevations - desc or something like that, always keep full things "description"