Imagine you're designing a restaurant menu. You could write "Get me a pizza" or "Give me pizza #5", both communicate the same thing, but one is more consistent and scalable. RESTWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. APIs work the same way. They provide a standardized way for different systems to communicate, making your APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. predictable and easy to use.
What is RESTWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources.?
REST (Representational State Transfer) is an architectural style, not a technology. It's a set of guidelines for designing networked applications. Think of it as the etiquette of web APIs, rules that make communication smooth and predictable.
The core idea: treat everything as a resource. Users are resources. Blog posts are resources. Orders are resources. You perform actions on these resources using standard HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. methods.
Resources, not actions
This is where beginners often stumble. Your URLs should name things (nouns), not actions (verbs).
❌ WRONG: URLs with verbs
GET /getUsers
POST /createUser
PUT /updateUser/123
DELETE /deleteUser/123
✅ RIGHT: URLs with nouns, HTTP verbs for actions
GET /users # List all users
GET /users/123 # Get user 123
POST /users # Create a new user
PUT /users/123 # Replace user 123 entirely
PATCH /users/123 # Update specific fields of user 123
DELETE /users/123 # Delete user 123See the pattern? The URL identifies what you're working with. The HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. method tells you what to do with it.
HTTP methods explained
| Method | Action | Idempotent? | Safe? |
|---|---|---|---|
| GET | Read data | Yes | Yes |
| POST | Create new resource | No | No |
| PUT | Replace entire resource | Yes | No |
| PATCH | Partial update | No | No |
| DELETE | Remove resource | Yes | No |
IdempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe. means doing it multiple times has the same effect as doing it once. Sending DELETE /users/123 five times still results in one deleted user. POST is not idempotent, five POST requests create five users.
Safe means it doesn't change server state. GET requests should never modify data.
Resource relationships
Real-world data is connected. Users have posts. Posts have comments. RESTWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. represents these relationships through URL nesting:
GET /users/123/posts # All posts by user 123
GET /users/123/posts/456 # Specific post 456 by user 123
POST /users/123/posts # Create a post for user 123
GET /posts/456/comments # Comments on post 456
POST /posts/456/comments # Add comment to post 456/users/123/posts/456/comments/789 is pushing it. Consider flattening to /comments/789 with filtering instead.StatelessWhat is stateless?A design where each request contains all the information the server needs, so any server can handle any request without remembering previous ones. architecture
Each request to your APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. must contain everything the server needs to fulfill it. The server doesn't remember previous requests or maintain client state between calls.
What this means in practice:
- Every request includes authenticationWhat is authentication?Verifying who a user is, typically through credentials like a password or token. (usually a tokenWhat is token?The smallest unit of text an LLM processes - roughly three-quarters of a word. API pricing is based on how many tokens you use.)
- No server-side sessions storing user state
- No assumption that request B comes from the same client as request A
GET /api/users/123 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
# Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 123,
"name": "Alice",
"email": "alice@example.com"
}This statelessness makes your API scalable. Any server can handle any request, no need to route users back to the same machine that handled their previous request.
HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. status codes
Status codes tell the client what happened without parsing the response body. They're grouped by the first digit:
| Code | Category | Common Uses |
|---|---|---|
| 200 | Success | GET request succeeded |
| 201 | Created | POST request created resource |
| 204 | No Content | DELETE succeeded, nothing to return |
| 400 | Bad Request | Invalid JSON or missing required field |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Authenticated but not allowed |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Resource already exists (duplicate email) |
| 422 | Unprocessable | Validation failed |
| 500 | Server Error | Unexpected server error |
Using appropriate status codes helps APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. consumers handle responses correctly. A 404 tells them to stop retrying, the resource is gone. A 500 tells them to retry later, it might be temporary.
Response structure
Consistent response formats make APIs easier to consume. Here's a standard pattern:
Success response
{
"status": "success",
"data": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
}List with paginationWhat is pagination?Splitting a large set of results into smaller pages so the server and client only handle a manageable chunk at a time.
{
"status": "success",
"data": [
{ "id": 1, "name": "John" },
{ "id": 2, "name": "Jane" }
],
"meta": {
"pagination": {
"page": 1,
"per_page": 20,
"total": 100,
"total_pages": 5
}
}
}Error response
{
"status": "error",
"message": "User not found",
"code": "USER_NOT_FOUND"
}Wrapping data in a data field might seem redundant for simple responses, but it pays off when you need to add metadata, pagination, or links (HATEOASWhat is hateoas?A REST constraint where API responses include hyperlinks to related actions, so clients can discover available operations without hardcoding URLs.) later.
Implementing RESTWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. in Express
Let's put theory into practice with a complete Express implementation:
import express from 'express';
const app = express();
app.use(express.json());
// GET /users - List all users with pagination
app.get('/users', async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 20;
const users = await db.getUsers(page, limit);
const total = await db.countUsers();
res.json({
status: 'success',
data: users,
meta: {
pagination: {
page,
per_page: limit,
total,
total_pages: Math.ceil(total / limit)
}
}
});
});
// GET /users/:id - Get specific user
app.get('/users/:id', async (req, res) => {
const user = await db.getUserById(req.params.id);
if (!user) {
return res.status(404).json({
status: 'error',
message: 'User not found'
});
}
res.json({
status: 'success',
data: user
});
});
// POST /users - Create new user
app.post('/users', async (req, res) => {
try {
const user = await db.createUser(req.body);
res.status(201).json({
status: 'success',
data: user
});
} catch (error) {
res.status(400).json({
status: 'error',
message: error.message
});
}
});
// PUT /users/:id - Replace entire user
app.put('/users/:id', async (req, res) => {
const user = await db.updateUser(req.params.id, req.body);
res.json({
status: 'success',
data: user
});
});
// PATCH /users/:id - Partial update
app.patch('/users/:id', async (req, res) => {
const user = await db.patchUser(req.params.id, req.body);
res.json({
status: 'success',
data: user
});
});
// DELETE /users/:id - Remove user
app.delete('/users/:id', async (req, res) => {
await db.deleteUser(req.params.id);
res.status(204).send();
});Notice how each endpointWhat is endpoint?A specific URL path on a server that handles a particular type of request, like GET /api/users. follows REST conventions:
- URLs identify resources
- HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. methods determine the action
- Status codes indicate success or failure
- Consistent JSONWhat is json?A text format for exchanging data between systems. It uses key-value pairs and arrays, and every programming language can read and write it. response format
Quick reference: RESTWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. design checklist
| Check | Guideline |
|---|---|
| ✅ | URLs are nouns, not verbs |
| ✅ | HTTP methods match CRUD operations |
| ✅ | Appropriate status codes used |
| ✅ | Stateless requests (auth in every request) |
| ✅ | Consistent response format |
| ✅ | Resource relationships shown in URLs |
| ✅ | Pagination for list endpoints |
REST isn't the only way to build APIs, but it's the most widely adopted standard. Master these principles, and you'll build APIs that other developers actually enjoy using.