# HTTP & REST Cheatsheet

For L7 (Fetch + REST) and L10 (backend APIs).

## Anatomy of an HTTP request

```
POST /api/students HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...

{"name":"Asha","email":"asha@x.com"}
```

## Methods

| Method   | Purpose                          | Idempotent | Safe |
|----------|----------------------------------|------------|------|
| `GET`    | Retrieve a resource              | ✓          | ✓    |
| `POST`   | Create a resource                | ✗          | ✗    |
| `PUT`    | Replace a resource (full update) | ✓          | ✗    |
| `PATCH`  | Partial update                   | sometimes  | ✗    |
| `DELETE` | Remove a resource                | ✓          | ✗    |
| `HEAD`   | GET without body                 | ✓          | ✓    |
| `OPTIONS`| CORS preflight, capabilities     | ✓          | ✓    |

**Idempotent** = same result no matter how many times you call it.
**Safe** = doesn't change server state.

## Status codes

| Range | Meaning |
|-------|---------|
| 1xx   | Informational |
| 2xx   | Success |
| 3xx   | Redirection |
| 4xx   | Client error |
| 5xx   | Server error |

Common ones:

- **200** OK
- **201** Created (with `Location:` header pointing to new resource)
- **204** No Content (e.g. successful DELETE)
- **301 / 302** Moved permanently / Found
- **400** Bad Request — validation error
- **401** Unauthorised — missing/invalid auth
- **403** Forbidden — authenticated but not allowed
- **404** Not Found
- **409** Conflict — duplicate, version mismatch
- **422** Unprocessable Entity — semantic validation error
- **429** Too Many Requests — rate-limited
- **500** Internal Server Error
- **502 / 503 / 504** Bad gateway / Service unavailable / Gateway timeout

## REST resource design

```
GET    /api/students            list all
POST   /api/students            create
GET    /api/students/42         read one
PUT    /api/students/42         replace
PATCH  /api/students/42         update fields
DELETE /api/students/42         remove

GET    /api/students/42/courses     nested resource
```

Use **nouns** (resources), not verbs. Plural collections.

### Filtering, paging, sorting

```
GET /api/students?age_gt=18&sort=-created_at&page=2&limit=20
```

## Common headers

| Header | Use |
|--------|-----|
| `Content-Type: application/json` | Body format you're sending |
| `Accept: application/json`       | Body format you want back |
| `Authorization: Bearer <token>`  | Auth (JWT/OAuth) |
| `Cache-Control: no-store`        | Don't cache |
| `ETag` / `If-None-Match`         | Conditional GET |
| `Location: /api/students/42`     | Where the new resource lives (after 201) |

## Fetch (browser)

```js
const res = await fetch("/api/students", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Asha" }),
});

if (!res.ok) {
  throw new Error(`HTTP ${res.status}: ${await res.text()}`);
}
const created = await res.json();
```

## CORS — cross-origin requests

If the frontend (e.g. `localhost:5173`) calls a different origin (e.g. `localhost:8080`), the server must respond with:

```
Access-Control-Allow-Origin: http://localhost:5173
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
```

For "non-simple" requests (custom headers, PUT/DELETE), the browser sends a preflight `OPTIONS`. Configure CORS once in your backend.

## REST vs RPC

REST: noun-based (`POST /students`).
RPC: verb-based (`POST /createStudent`). Both are valid; this course uses REST.

## Tools

- HTTPie: <https://httpie.io/> (`http GET :8080/api/students`)
- curl examples:
  ```bash
  curl -i http://localhost:8080/api/students
  curl -X POST -H 'Content-Type: application/json' \
       -d '{"name":"Asha"}' http://localhost:8080/api/students
  ```
- Postman: <https://www.postman.com/>
- Insomnia: <https://insomnia.rest/>
- httpbin (test endpoint): <https://httpbin.org/>
