$ Vraj Ved _

Latest Commit: September 17, 2026

← Back to blog

Backend Basics #4

2026-05-01·15 min Read

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

  1. Client Server Model
  2. Uniform Inference
  3. Layered System
  4. Cache
  5. Statelessness
  6. Code on Demand

Core REST vocabulary

TermMeaning
RepresentationalResources on the web are specified in various formats, example JSON, xml, HTML, etc.
StateCurrent condition / attribute of the resource
Transfermovement 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

  1. Start with UI design interface and follow the wireframe - you have an idea how the users will interact with the data.
  2. Resources are the nouns you can find, example - projects, users, organizations, tasks, tags, etc.
  3. 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;
}
  1. 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

MethodEndpointAction
POST/organizationsCreate Org
GET/organizationsList Orgs
GET/organizations/:idGet Org
PATCH/organizations/:idUpdate Org
DELETE/organizations/:idDelete Org
POST/organizations/:id/archiveArchive 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

  1. Interactive Documentation - Start using swagger api to start documenting things, how frequently you maintain your API
  2. Keep things intuitive and consistent - Follow standards and do not change your patterns
  3. Provide Sane defaults - If nothing is passed by the client, there is a default fallback
  4. Avoid abbrevations - desc or something like that, always keep full things "description"