What Is REST?
REST (Representational State Transfer) is an architectural style for building web APIs, defined by Roy Fielding in his 2000 doctoral dissertation. The core idea is simple:
- Resources are identified by URLs (
/api/books,/api/books/42) - HTTP methods are the verbs that act on those resources (GET, POST, PUT, DELETE)
- Representations (usually JSON) are how resources are transferred between client and server
- Each request is stateless — it contains all the information the server needs
Think of it this way: URLs are nouns, HTTP methods are verbs.
CRUD and REST
REST maps the four basic data operations (CRUD) to HTTP methods:
| CRUD Operation | HTTP Method | Collection URL | Item URL |
|---|---|---|---|
| Create | POST | /api/books |
— |
| Read | GET | /api/books |
/api/books/42 |
| Update | PUT / PATCH | — | /api/books/42 |
| Delete | DELETE | — | /api/books/42 |
There are two URL patterns:
/api/resource— the collection (all books)/api/resource/:id— a specific item (book #42)
URL Design: The RESTful Spectrum
Not all API URLs are equally RESTful. URLs should name resources (nouns), not actions (verbs):
| URL | RESTfulness | Why |
|---|---|---|
GET /api/books/1 |
RESTful | Resource in the URL, method implies action |
GET /api/books?id=1 |
Less RESTful | Works, but ID should be in the path |
GET /api?record=books&id=1 |
Not RESTful | Resource type hidden in query params |
GET /api?id=1&action=delete |
Definitely not REST | Action in URL, wrong HTTP method for delete |
Status Codes for REST APIs
A REST API communicates results through HTTP status codes. Using the right code tells the client exactly what happened.
Status Codes by CRUD Operation
| Operation | Success | Common Errors |
|---|---|---|
| POST (Create) | 201 Created |
400 Bad input, 409 Conflict |
| GET (Read) | 200 OK |
404 Not found |
| PUT/PATCH (Update) | 200 OK |
404 Not found, 400 Bad input |
| DELETE | 200 or 204 No Content |
404 Not found |
Key client error codes: 400 (malformed request), 401 (not authenticated), 403 (not authorized), 404 (not found), 405 (method not allowed), 409 (conflict), 422 (valid JSON but semantically invalid), 429 (rate limited).
PUT vs PATCH
Both update a resource, but they have different semantics:
| Aspect | PUT | PATCH |
|---|---|---|
| Semantics | Full replacement — send the entire resource | Partial update — send only changed fields |
| Missing fields | Should be set to defaults or removed | Left unchanged |
| Idempotent? | Yes — same PUT twice = same result | Not guaranteed |
Richardson Maturity Model
Leonard Richardson described a maturity model for REST APIs with four levels:
┌─────────────────────┐
│ Level 3 │
│ Hypermedia Controls│ ← HATEOAS: responses include links
│ (HATEOAS) │ to related actions/resources
┌─┴─────────────────────┴─┐
│ Level 2 │
│ HTTP Verbs + Status │ ← GET/POST/PUT/DELETE + proper
│ Codes │ status codes (200, 201, 404...)
┌─┴─────────────────────────┴─┐
│ Level 1 │
│ Individual Resources │ ← Different URLs per resource
│ /users /books /orders │ (/users, /books, /orders)
┌─┴─────────────────────────────┴─┐
│ Level 0 │
│ "The Swamp of POX" │ ← One URL, POST everything
│ POST /api (do everything here)│ (like XML-RPC or SOAP)
└─────────────────────────────────┘
Most modern APIs aim for Level 2 and that's generally sufficient. Level 3 (HATEOAS) is the full REST ideal but adds complexity many teams don't need.
HATEOAS
At Level 3, API responses include links that tell the client what it can do next. Instead of hardcoding API URLs, the client discovers them dynamically:
The GitHub API is one of the best real-world examples of HATEOAS. Try curl https://api.github.com/users/tj — the response includes URLs for repos, followers, and organizations without the client needing to construct them.