API & BACKEND ARCHITECTURE / SYSTEM CONCEPT BRIEF

REST

REST (Representational State Transfer) is an architectural style for APIs built on HTTP.

BeginnerPhase 02 / Topic 1 of 20RequirementsTrade-offsFailure modes
01

Overview

REST (Representational State Transfer) is an architectural style for APIs built on HTTP. Everything is a resource identified by a URL (/users/42/orders), clients manipulate resources with standard methods (GET, POST, PUT, PATCH, DELETE), and every request is stateless: it carries all the information the server needs.

REST's strength is uniformity. Because it reuses HTTP semantics, it works with every client, proxy, and CDN, and responses can be cached with standard headers. Its weaknesses are over-fetching and under-fetching (returning too much or needing several calls), which GraphQL and gRPC address in different ways.

A library catalog

Every book has a fixed shelf address (URL). You can look at it (GET), add a new book (POST), replace it (PUT), fix a detail (PATCH), or remove it (DELETE). The librarian does not remember you between visits; you show your card each time (stateless).

02

When to use it

  • Public APIs consumed by many different clients.
  • CRUD-style domains (users, products, orders).
  • When HTTP caching and CDN support matter.
  • Simple integration with browsers, mobile apps, and partners.
03

Where it shows up in interviews

Resource modeling

Recognize it when: design the endpoints for a domain.

  • Design the API for Twitter
  • Design an e-commerce cart API
  • Design a URL shortener API
Pagination and filtering

Recognize it when: large collections returned to clients.

  • Design a news feed API
  • Design a search results API
04

Where it is used in real software

Stripe API

A widely admired REST API: consistent resource URLs, idempotency keys on POST, cursor pagination, and versioning by date.

GitHub REST API

Uses hypermedia links, conditional requests with ETags, and rate limit headers.

OpenAPI

The OpenAPI (Swagger) specification documents REST APIs and generates clients and servers.

05

Key terms

Resource
A noun addressed by a URL: /orders/9001.
Stateless
The server keeps no client session between requests; each request is self-contained.
Idempotency
PUT and DELETE can be repeated safely; POST needs an idempotency key.
HATEOAS
Responses include links to related actions; rarely fully implemented in practice.
Cursor pagination
Clients page with an opaque cursor instead of page numbers.
06

Designing a REST resource

  1. 1
    Name resources as plural nouns

    /orders, /orders/{id}, /users/{id}/orders. Avoid verbs like /getOrders.

  2. 2
    Map actions to methods

    GET list or item, POST create, PATCH update, DELETE remove.

  3. 3
    Choose status codes

    201 with Location on create, 204 on delete, 400/404/409 for client errors.

  4. 4
    Support filtering and pagination

    GET /orders?status=paid&limit=50&cursor=abc.

  5. 5
    Version and document

    /v1/ prefix or a version header, with an OpenAPI spec.

07

Endpoints for an orders resource

Consistent URLs, methods, and responses

Step 1 / 5
ActionMethod + pathSuccessNotes
List ordersGET /v1/orders?limit=50&cursor=x200Returns data + next_cursor
Get one orderGET /v1/orders/9001200 / 404ETag for caching
Create orderPOST /v1/orders201 + LocationIdempotency-Key header
Update statusPATCH /v1/orders/9001200If-Match for optimistic locking
Cancel orderDELETE /v1/orders/9001204Or POST /orders/9001/cancel for a business action

NOWAction: List orders | Method + path: GET /v1/orders?limit=50&cursor=x | Success: 200 | Notes: Returns data + next_cursor

Business actions that are not simple CRUD (cancel, refund) are often modeled as sub-resources or POST actions; consistency matters more than purity.

08

Implementation

import express from "express"; const app = express();app.use(express.json()); app.get("/v1/orders", async (req, res) => {  const limit = Math.min(Number(req.query.limit ?? 50), 100);  const { items, nextCursor } = await orders.list({ cursor: req.query.cursor as string, limit });  res.json({ data: items, next_cursor: nextCursor });}); app.post("/v1/orders", async (req, res) => {  const key = req.header("Idempotency-Key");  if (!key) return res.status(400).json({ error: "Idempotency-Key required" });  const existing = await idempotency.get(key);  if (existing) return res.status(existing.status).json(existing.body); // replay   const order = await orders.create(req.body);  await idempotency.save(key, { status: 201, body: order });  res.status(201).location(`/v1/orders/${order.id}`).json(order);}); app.delete("/v1/orders/:id", async (req, res) => {  await orders.cancel(req.params.id);  res.status(204).end();});
09

Complexity and performance

Requests per screen1-N

Can require several round trips.

CacheabilityHigh

GET responses with standard headers.

Payload sizeFixed by server

May over-fetch.

10

Trade-offs

REST vs GraphQL

REST is simple, cacheable, and universal; GraphQL lets clients fetch exactly what they need in one request but is harder to cache and secure.

REST vs gRPC

gRPC is faster and strongly typed for service-to-service calls; REST is friendlier for browsers and public APIs.

Offset vs cursor pagination

Offsets are simple but slow and inconsistent on large, changing data; cursors are stable and efficient.

11

Variants and related techniques

JSON:API

A convention for consistent REST payloads, relationships, and errors.

Backend for frontend

A REST layer tailored to one client (mobile, web) that aggregates internal calls.

12

Common mistakes

  • Verbs in URLs (/createOrder).

    Fix: Use nouns and HTTP methods: POST /orders.

  • Returning unbounded lists.

    Fix: Always paginate and cap the limit.

  • Breaking changes without versioning.

    Fix: Add fields freely; remove or rename only in a new version.

13

Interview questions

Why is statelessness important in REST?

Any server can handle any request, which allows horizontal scaling behind a load balancer and makes failures easier to recover from.

How do you make POST safe to retry?

Require an Idempotency-Key header. Store the result for each key; if the same key is retried, return the stored result instead of creating a duplicate.

How do you version a REST API?

Common options are a path prefix (/v1), a header, or date-based versions (Stripe). Keep changes additive where possible and support old versions for a deprecation period.

14

Practice problems

ProblemDifficultyWhat it trains
Design REST endpoints for a blogEasyResources and methods.
Design the Stripe-like payments APIMediumIdempotency and errors.
Design pagination for a feed with 1B itemsMediumCursors.