> ## Documentation Index
> Fetch the complete documentation index at: https://docs.loremstock.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Designing and Understanding RESTful APIs

> Learn the 6 REST constraints, HTTP methods, status codes, and how to structure clean, predictable API routes in Express with resource-oriented design.

REST (Representational State Transfer) is the most widely adopted architectural style for web APIs. Understanding its principles is essential not just for building APIs, but for explaining your design decisions. This page covers every REST concept you need: the six constraints, HTTP methods, status codes, URL design rules, and how to put it all into practice with Express.

## What Is REST?

REST is an architectural style introduced by Roy Fielding in 2000. It is a set of guidelines for designing networked applications over HTTP. REST is not a protocol, library, or framework.

In REST, everything is a **resource** (a user, order, product) identified by a unique URL. Clients interact with resources using standard HTTP methods.

## The 6 REST Constraints

<Steps>
  <Step title="Client-Server">
    Client (handles UI) and server (handles data/logic) are separate systems communicating over HTTP. Each can evolve independently.
  </Step>

  <Step title="Stateless">
    The server stores NO client session state between requests. Every request must contain all information needed. Authentication tokens, not server sessions.
  </Step>

  <Step title="Cacheable">
    Responses must indicate whether they can be cached. Caching reduces server load for repeated requests.
  </Step>

  <Step title="Uniform Interface">
    All resources use consistent URL patterns and HTTP methods. The API is predictable regardless of resource type.
  </Step>

  <Step title="Layered System">
    The client cannot tell if it is connected to the actual server or an intermediary (load balancer, cache, gateway). Layers are transparent.
  </Step>

  <Step title="Code on Demand (optional)">
    Servers can send executable code to clients (e.g., JavaScript). Rarely used. The only optional constraint.
  </Step>
</Steps>

<Note>
  **Stateless** is the most exam-relevant constraint. It means the server never stores session data in memory. Each request from a client must include auth credentials (like a JWT token). This enables horizontal scaling.
</Note>

## HTTP Methods

| Method | Action                     | Idempotent? | Safe? |
| ------ | -------------------------- | ----------- | ----- |
| GET    | Read resource(s)           | Yes         | Yes   |
| POST   | Create new resource        | No          | No    |
| PUT    | Full replace of resource   | Yes         | No    |
| PATCH  | Partial update of resource | Yes         | No    |
| DELETE | Remove resource            | Yes         | No    |

**Idempotent** = calling the same operation multiple times gives the same result. **Safe** = the operation does not change server state.

<Tip>
  Exam tip: POST is the only non-idempotent method. Calling `POST /users` twice creates two users. Calling `DELETE /users/1` twice deletes once then returns 404 (same end state).
</Tip>

## HTTP Status Codes

Memorize these. Exams test status code knowledge heavily.

| Code    | Name                  | When to Use                                           |
| ------- | --------------------- | ----------------------------------------------------- |
| **200** | OK                    | Successful GET, PUT, PATCH                            |
| **201** | Created               | Successful POST (resource was created)                |
| **204** | No Content            | Successful DELETE (nothing to return)                 |
| **400** | Bad Request           | Client sent malformed data or missing required fields |
| **401** | Unauthorized          | Not authenticated — "who are you?"                    |
| **403** | Forbidden             | Authenticated but no permission — "you can't do that" |
| **404** | Not Found             | Resource does not exist                               |
| **409** | Conflict              | Duplicate resource (e.g., email already registered)   |
| **422** | Unprocessable Entity  | Validation failed on valid JSON                       |
| **500** | Internal Server Error | Server crashed or unhandled exception                 |

<Warning>
  **401 vs 403 is a classic exam question.** 401 = "You are not logged in." 403 = "You are logged in, but you don't have permission." Never mix them up.
</Warning>

## URL Design Best Practices

<Steps>
  <Step title="Use nouns, not verbs">
    The HTTP method is the verb. The URL is the noun.

    ```text theme={null}
    GOOD:  GET /users
    BAD:   GET /getUsers
    GOOD:  DELETE /users/5
    BAD:   GET /deleteUser?id=5
    ```
  </Step>

  <Step title="Use plural resource names">
    ```text theme={null}
    GOOD:  /users, /products, /orders
    BAD:   /user, /product, /order
    ```
  </Step>

  <Step title="Use nesting for relationships">
    ```text theme={null}
    GET /users/42/posts        — all posts by user 42
    GET /users/42/posts/7      — post 7 by user 42
    POST /users/42/posts       — create a post for user 42
    ```
  </Step>

  <Step title="Use lowercase with hyphens">
    ```text theme={null}
    GOOD:  /blog-posts
    BAD:   /BlogPosts, /blog_posts
    ```
  </Step>
</Steps>

## Request and Response Anatomy

### HTTP Request

```http theme={null}
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

{
  "name": "Alice Smith",
  "email": "alice@example.com"
}
```

| Part                     | How to access in Express            |
| ------------------------ | ----------------------------------- |
| Method                   | `req.method`                        |
| URL path                 | `req.path`                          |
| Path parameters (`:id`)  | `req.params.id`                     |
| Query string (`?page=2`) | `req.query.page`                    |
| Headers                  | `req.headers['authorization']`      |
| Body (JSON)              | `req.body` (needs `express.json()`) |

### HTTP Response

```http theme={null}
HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": 42,
  "name": "Alice Smith",
  "email": "alice@example.com",
  "createdAt": "2024-01-15T09:30:00Z"
}
```

## REST vs SOAP vs GraphQL

| Feature        | REST            | SOAP               | GraphQL                    |
| -------------- | --------------- | ------------------ | -------------------------- |
| Protocol       | HTTP            | HTTP, SMTP, others | HTTP                       |
| Format         | JSON, XML       | XML only           | JSON                       |
| Flexibility    | Fixed endpoints | Strict contracts   | Client defines query shape |
| Caching        | Excellent       | Moderate           | Difficult                  |
| Learning curve | Low             | High               | Medium                     |
| Best for       | Most web APIs   | Enterprise/banking | Complex nested data        |

## Full /users Route Example in Express

```javascript theme={null}
// routes/users.js
const express = require('express');
const router = express.Router();

let users = [
  { id: 1, name: 'Alice', email: 'alice@example.com' },
  { id: 2, name: 'Bob', email: 'bob@example.com' }
];
let nextId = 3;

// GET /users — list all
router.get('/', (req, res) => {
  res.status(200).json(users);
});

// GET /users/:id — get one
router.get('/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });
  res.status(200).json(user);
});

// POST /users — create
router.post('/', (req, res) => {
  const { name, email } = req.body;
  if (!name || !email) {
    return res.status(400).json({ message: 'Name and email required' });
  }
  if (users.find(u => u.email === email)) {
    return res.status(409).json({ message: 'Email already exists' });
  }
  const newUser = { id: nextId++, name, email };
  users.push(newUser);
  res.status(201).json(newUser);
});

// PUT /users/:id — full update
router.put('/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });
  const { name, email } = req.body;
  if (!name || !email) return res.status(400).json({ message: 'Name and email required' });
  user.name = name;
  user.email = email;
  res.status(200).json(user);
});

// PATCH /users/:id — partial update
router.patch('/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });
  if (req.body.name) user.name = req.body.name;
  if (req.body.email) user.email = req.body.email;
  res.status(200).json(user);
});

// DELETE /users/:id
router.delete('/:id', (req, res) => {
  const index = users.findIndex(u => u.id === parseInt(req.params.id));
  if (index === -1) return res.status(404).json({ message: 'User not found' });
  users.splice(index, 1);
  res.status(204).send();
});

module.exports = router;
```

Mount in `app.js`:

```javascript theme={null}
const userRoutes = require('./routes/users');
app.use('/api/v1/users', userRoutes);
```

## Testing with Postman

<Steps>
  <Step title="Create a request">
    Open Postman, click New > HTTP Request.
  </Step>

  <Step title="Set method and URL">
    e.g., POST [http://localhost:3000/api/v1/users](http://localhost:3000/api/v1/users)
  </Step>

  <Step title="Add Content-Type header">
    Headers tab: `Content-Type: application/json`
  </Step>

  <Step title="Add body">
    Body tab > raw > JSON: `{"name": "Alice", "email": "alice@test.com"}`
  </Step>

  <Step title="Send and inspect">
    Click Send. Check the status code and response body.
  </Step>
</Steps>

## Key Terms

| Term               | Definition                                                             |
| ------------------ | ---------------------------------------------------------------------- |
| **REST**           | Representational State Transfer. An architectural style for HTTP APIs. |
| **Resource**       | Any named item accessible via a URL (user, order, product).            |
| **Endpoint**       | A URL path + HTTP method combination.                                  |
| **Payload**        | Data sent in the request body.                                         |
| **Idempotent**     | Same operation, same result no matter how many times called.           |
| **Stateless**      | Server stores nothing about clients between requests.                  |
| **Status code**    | 3-digit number in a response indicating the outcome.                   |
| **Query string**   | Optional key-value pairs after `?` in a URL for filtering/pagination.  |
| **Path parameter** | Variable URL segment like `:id` in `/users/:id`.                       |
