# 21 • RESTful

> AJAX, REST, JSON, XML, chybové a návratové kódy, vracení dat, Web API, význam metod
> 

<aside>
😡

#### **Je to RESTful (REST + ful) jako playful (play + ful) - ne RESTfull, jak píše Kazda pořád dokola!!**

</aside>

# **Co je API**

**API** *(Application Programming Interface)* je rozhraní, přes které spolu komunikují aplikace nebo její části. Definuje, **jaké operace lze provést a jak**, ale skrývá interní implementaci.

### Typy API

| Typ | Kde se používá | Příklad |
| --- | --- | --- |
| **Webové API** | Komunikace přes HTTP | REST, GraphQL, gRPC |
| **Knihovní API** | V rámci programu | DOM API, fs (Node.js), React API |
| **Operační systém** | Aplikace ↔ OS | POSIX, Win32 |
| **Grafické** | GPU akcelerace | OpenGL, Vulkan, DirectX, WebGL |
| **Hardwarové** | Komunikace s HW | I2C, SPI, USB |

V kontextu webu se "API" typicky myslí **HTTP API** vystavené serverem pro klienty (web, mobil, partneři).

---

# **REST: architektonický styl**

**REST *(Representational State Transfer)* je architektonický styl pro tvorbu distribuovaných systémů, popsaný Royem Fieldingem v jeho disertaci v roce 2000. Není to standard, je to soubor principů.**

<aside>
💡

**REST vs RESTful**: REST je striktní architektura podle Fieldinga. "RESTful" se v praxi používá jako volnější označení pro API, které dodržuje hlavní principy. Většina "REST API" v praxi je vlastně RESTful, ne čisté REST.

</aside>

### 6 architektonických omezení (constraints) REST

1. **Client-Server** (oddělení zájmů): klient se stará o UI, server o data a logiku. Mohou se vyvíjet nezávisle.
2. **Stateless** (bezstavový): každý request obsahuje **vše potřebné** pro zpracování. Server si nepamatuje předchozí requesty od daného klienta.
3. **Cacheable** (cachovatelný): odpovědi musí být **explicitně označené** jako cachovatelné nebo ne (přes hlavičky `Cache-Control`, `ETag`).
4. **Uniform Interface** (jednotné rozhraní): konzistentní princip identifikace zdrojů (URI), manipulace přes reprezentace (JSON, XML), self-descriptive messages.
5. **Layered System** (vrstvená architektura): klient neví, jestli mluví přímo se serverem nebo přes proxy/load balancer/CDN.
6. **Code on Demand** *(volitelné)*: server může poslat klientovi kód k provedení (např. JavaScript). Jediné nepovinné omezení.

### Richardson Maturity Model

jak moc jsou dodržovány REST principy:

| Level | Princip | Typický příklad |
| --- | --- | --- |
| **Level 0** | Jedno URL, jedna metoda (typicky POST) | SOAP, RPC |
| **Level 1** | Více URL pro různé zdroje | `/users`, `/products` |
| **Level 2** | Použití HTTP metod (GET/POST/PUT/DELETE) | "Klasické" REST API |
| **Level 3** | HATEOAS (hypermedia) | Odkazy v odpovědích na další akce |

Většina dnešních "REST API" je na Level 2. Level 3 (HATEOAS) je v praxi vzácný.

### HATEOAS

**Hypermedia As The Engine Of Application State**: API odpovědi obsahují **odkazy na další možné akce**, takže klient nepotřebuje znát strukturu URL předem.

```json
{
  "id": 42,
  "name": "Axo",
  "_links": {
    "self": { "href": "/users/42" },
    "posts": { "href": "/users/42/posts" },
    "edit": { "href": "/users/42", "method": "PUT" }
  }
}
```

Plus: API je samodokumentující. Mínus: implementačně náročnější, klienti to typicky nevyužívají.

---

# Klasická vs asynchronní komunikace

|  | Klasická (server-rendered) | Asynchronní (AJAX) |
| --- | --- | --- |
| **Kdy se posílá request** | Při změně stránky | Kdykoli, na pozadí |
| **Co server vrací** | Celé HTML | JSON s daty |
| **Reload stránky** | Ano, při každé akci | Ne |
| **Latence vnímaná uživatelem** | Vyšší | Nižší (částečný update) |
| **Příklad** | Tradiční PHP web, Wikipedia | Gmail, Google Maps, Figma |

# **AJAX: Asynchronous JavaScript and XML**

**AJAX** je technika pro komunikaci se serverem **bez nutnosti reloadu stránky**. Pojem se vžil v roce 2005 (Jesse James Garrett) po prvních AJAX-heavy aplikacích od Googlu (Gmail 2004, Google Maps 2005). Tyto aplikace ukázaly, že web umí konkurovat desktopu.

> **Drobnost:** "XML" v názvu je dnes anachronismus. AJAX se v 95+ % případů používá s **JSON**, ne XML. Pojem ale zůstal.
> 

### Princip

![image.png](21%20%E2%80%A2%20RESTful/image.png)

### Typické use cases

- Našeptávač ve search baru
- Chat (nové zprávy se objevují)
- Dynamický scroll (lazy load, infinite scroll)
- Validace formulářů "za běhu"
- Lajk tlačítko, koš v e-shopu
- Notifikace, real-time dashboardy

### **Implementace: tři generace**

### 1. XMLHttpRequest (XHR) - klasika z 2000

Stará API, pořád funguje. Sleduje progress, ale syntakticky nešikovná (callbacks).

```jsx
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/users');
xhr.onload = () => console.log(xhr.response);
xhr.onerror = () => console.error('Error');
xhr.send();
```

### Fetch API - moderní default (od 2015)

Vrací Promise. Cleaner syntaxe.

```jsx
// GET
const response = await fetch('/api/users');
const data = await response.json();

// POST s tělem
const response = await fetch('/api/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'axo', age: 18 })
});

if (response.ok) {
  const newUser = await response.json();
}
```

> **Chyták s Fetch:** `fetch` **neodmítne Promise** při HTTP 4xx/5xx odpovědi (na rozdíl od axios). Promise se rejectne **jen při síťové chybě** (DNS, no connection). Pro HTTP chyby musíš kontrolovat `response.ok` sám.
> 

### Axios, ky, ofetch - knihovny

Knihovny postavené nad fetch/XHR s lepší ergonomií.

```jsx
// Axios
const { data } = await axios.get('/api/users');
await axios.post('/api/users', { name: 'Axo' });

// Auto-throw na 4xx/5xx
try {
  const { data } = await axios.get('/api/users/999');
} catch (error) {
  if (error.response?.status === 404) { /* ... */ }
}
```

### Promises a async/await

Promise reprezentuje **asynchronní operaci** se třemi stavy:

| Stav | Význam | Co s tím |
| --- | --- | --- |
| **Pending** | Operace probíhá | Čekat |
| **Fulfilled** | Úspěch, vyřešeno | `.then()` nebo `await` |
| **Rejected** | Selhání | `.catch()` nebo `try/catch` |

### Promise patterns

```jsx
// Sekvenční (jeden po druhém)
const user = await fetchUser();
const posts = await fetchPosts(user.id);

// Paralelní (oba najednou, čekáme na oba)
const [user, posts] = await Promise.all([
  fetchUser(),
  fetchPosts()
]);

// Paralelní, vrátit nejrychlejší
const fastest = await Promise.race([
  fetch('/api/v1/data'),
  fetch('/api/v2/data')
]);

// Paralelní, čekáme na všechny i s chybami
const results = await Promise.allSettled([
  fetchUser(),
  fetchPosts(),
  fetchComments()
]);
// results: [{status: 'fulfilled', value: ...}, {status: 'rejected', reason: ...}, ...]
```

## HTTP metody a jejich význam

| Metoda | CRUD | Co dělá | Tělo? | Bezpečná? | Idempotentní? |
| --- | --- | --- | --- | --- | --- |
| **GET** | Read | Získat zdroj | Ne | Ano | Ano |
| **POST** | Create | Vytvořit nový | Ano | Ne | Ne |
| **PUT** | Update | Nahradit celý | Ano | Ne | Ano |
| **PATCH** | Update | Upravit část | Ano | Ne | **Ne** (obecně) |
| **DELETE** | Delete | Smazat | Volitelně | Ne | Ano |
| **HEAD** | - | Jen hlavičky (jako GET) | Ne | Ano | Ano |
| **OPTIONS** | - | Dostupné metody (CORS) | Ne | Ano | Ano |

### Bezpečná (safe) metoda

Metoda, která **nemění stav serveru**. Můžeš ji volat libovolněkrát bez konzekvencí.

- `GET`, `HEAD`, `OPTIONS` = bezpečné
- Vše ostatní mění stav

> **Důležitý důsledek:** crawlery, prefetchery a "preview" tlačítka prohlížeče volají GET. Pokud tvoje GET endpoint něco smaže nebo upraví (anti-pattern), bude se to dít náhodně. Klasická chyba: `/users/delete?id=5` jako GET.
> 

### Idempotentní metoda

Metoda, jejíž **opakované volání má stejný efekt jako jednotlivé**.

- `GET` (nemění nic = stejné)
- `PUT` (nahradí celé = výsledek stejný i při opakování)
- `DELETE` (smazaný uživatel zůstane smazaný)
- `POST` (vytvoří **nový** záznam pokaždé = neidempotentní)
- `PATCH` (obecně neidempotentní, závisí na operaci)

**Praktický význam:** pokud klient nezná, jestli první request dorazil (timeout), idempotentní metody může bezpečně opakovat. Pro POST se používají **idempotency keys**: klient vygeneruje UUID a pošle ho v hlavičce, server pak odmítne duplicitní vytvoření se stejným key.

```html
POST /api/orders
Idempotency-Key: 7f9c2a3b-1234-5678-90ab-cdef12345678
```

**POST vs PUT vs PATCH (klasická matoucí trojka)**

```bash
# POST: vytvoř nový (server přidělí ID)
POST /api/users
{ "name": "Axo", "email": "..." }
→ 201 Created, Location: /api/users/42

# PUT: nahraď celý objekt (všechny fieldy)
PUT /api/users/42
{ "name": "Axo", "email": "...", "role": "admin" }
→ 200 OK

# PATCH: změň jen tyto fieldy
PATCH /api/users/42
{ "role": "admin" }
→ 200 OK (ostatní fieldy zůstanou nezměněné)
```

# URL design pro REST API

| Princip | Příklad |
| --- | --- |
| **Použij podstatná jména, ne slovesa** | `/users` ne `/getUsers` |
| **Plurály pro kolekce** | `/users`, `/products` |
| **Jednotné pojmenování** | Buď `/users` nebo `/user`, ne mix |
| **Vnořené zdroje** | `/users/42/posts` (posty uživatele 42) |
| **Hierarchie přes lomítka** | `/categories/15/products/3` |
| **Akce přes podzdroje, ne slovesa** | `/users/42/follow` (POST) místo `/followUser?id=42` |
| **Filtry, řazení v query** | `/posts?author=42&sort=date&order=desc` |

### **Příklady kompletního CRUD endpointu**

```bash
GET    /api/users              seznam (s paginací, filtrováním)
GET    /api/users/42           detail jednoho
POST   /api/users              vytvoř nového
PUT    /api/users/42           nahraď celého
PATCH  /api/users/42           uprav část
DELETE /api/users/42           smaž

GET    /api/users/42/posts     posty uživatele (vnořený zdroj)
POST   /api/users/42/follow    custom akce (jako podzdroj)
```

# Vracení dat: stránkování, filtrování, řazení

Vrátit 1000 záznamů najednou je špatně: pomalé, paměťově náročné, většinou zbytečné.

## Stránkování (pagination)

### Offset-based (klasické)

```json
GET /api/posts?page=2&limit=20
```

Vrátí 20 záznamů od pozice druhá stránka)

**+ Plus**: jednoduché, intuitivní.
- **Mínus**: nestabilní (pokud někdo přidá záznam mezi stránkami, posune se ti vše).

### Cursor-based (moderní pro velké datasety)

```bash
GET /api/posts?cursor=eyJpZCI6MTAwfQ&limit=20
```

Klient pošle "kurzor" (typicky ID nebo timestamp posledního záznamu z předchozí stránky). Server vrátí dalších 20 od kurzoru.

**Plus**: stabilní i při dynamických změnách.
**Mínus**: nelze skočit na "stránku 5".

Použití: Twitter feed, Instagram, Reddit, infinite scroll.

### Pagination v odpovědi

```json
{
  "data": [...],
  "meta": {
    "page": 2,
    "limit": 20,
    "total": 247,
    "totalPages": 13
  },
  "links": {
    "self": "/api/posts?page=2",
    "next": "/api/posts?page=3",
    "prev": "/api/posts?page=1",
    "first": "/api/posts?page=1",
    "last": "/api/posts?page=13"
  }
}
```

### Filtrování

```bash
/api/posts?author=42
/api/posts?status=published&category=tech
/api/products?price_min=100&price_max=500
/api/users?created_after=2026-01-01
```

### Řazení

```bash
/api/posts?sort=date              # vzestupně
/api/posts?sort=-date             # sestupně (mínus prefix)
/api/posts?sort=date,-views       # více sloupců
```

### Výběr polí (sparse fieldsets)

Klient si může říct, **která pole** chce vrátit:

```bash
/api/users?fields=id,name,email
```

Snižuje velikost odpovědi a zrychluje response time. Tohle GraphQL řeší elegantněji nativně.

### Expand / include vztažených dat

```bash
/api/posts?include=author,comments
```

Místo dvou requestů (jeden na post, druhý na autora) vrátí všechno najednou. Anti-pattern: vždy includovat všechno (přemíra dat).

# API versioning

API se časem vyvíjí. Breaking changes (rušení polí, změny formátů) musí být verzované, aby staré klienty nepřestaly fungovat.

### URL versioning (nejběžnější)

```bash
/api/v1/users
/api/v2/users
```

**Plus**: jasně vidět ve URL, snadné cachování.
**Mínus**: porušuje REST princip ("zdroj má jedno URI").

Většina velkých API (Stripe, GitHub, Twitter, Slack) používá právě **URL versioning** pro pragmatičnost.

### Header versioning

```bash
GET /api/users
Accept: application/vnd.example.v1+json
```

**Plus**: "čistší" URL.
**Mínus**: hůř se debugguje, klient na to musí myslet.

### Query parameter

```bash
/api/users?version=1
```

**Plus**: jednoduché.
**Mínus**: zase porušuje REST.

# Formáty dat

### JSON: dnešní standard

```json
{
  "name": "Radomír Mendřický",
  "age": 20,
  "isStudent": true,
  "isSuspicious": true,
  "address": {
    "street": "Hanychovská 67",
    "city": "Liberec"
  },
  "hobbies": ["coding", "stamina", "making out with women"]
}
```

**Plus:**

- Lehký, čitelný
- Nativní pro JavaScript (`JSON.parse`, `JSON.stringify`)
- Široká podpora ve všech jazycích
- Menší než XML

**Mínus:**

- Žádné typy (datum je string, čísla limitované IEEE 754)
- Žádné komenty
- Žádné schema by default (ale existuje JSON Schema)

### XML

```xml
<Person id="67">
  <Name>Reiser</Name>
  <Age>19</Age>
  <Address>
    <Street>Švermovka</Street>
    <City>Liberec</City>
  </Address>
</Person>
<!-- comment jako v html -->
```

**Plus:**

- Validace přes XSD/DTD schémata
- Atributy (`<book id="1">`)
- Mature ekosystém (XPath, XSLT)

**Mínus:**

- Verbózní (víc dat než JSON)
- Náročnější parsing
- Už není cool

**Kde se ještě používá:** SOAP API, RSS feedy, sitemap.xml, SVG, Office dokumenty (DOCX, XLSX), Java enterprise (pom.xml)

### YAML

```yaml
name: axo4xo
age: 18
hasMaturita: false
address:
  city: Liberec
hobbies:
  - coding
  - music
  - gaming
# komentář
```

**Plus:**

- Nejlepší čitelnost
- Komenty (`#`)
- Méně syntaktického šumu

**Mínus:**

- Whitespace je významný (chybný odsazení = chyba)
- Pomalejší parsing
- "Norway problem": `NO` se parsuje jako boolean false (YAML 1.1)

**Použití:** Docker Compose, GitHub Actions, Kubernetes, ESPHome

### Srovnání

|  | JSON | XML | YAML |
| --- | --- | --- | --- |
| **Čitelnost** | Dobrá | Horší | Nejlepší |
| **Velikost** | Malá | Velká | Malá |
| **Validace** | JSON Schema | DTD/XSD | Omezená |
| **Komenty** | Ne | Ano | Ano |
| **Pro API** | Standard | Legacy | Nepoužívá se |
| **Pro config** | Občas | Občas | Standard |

### Binární alternativy

Pro vysoce výkonné komunikace (mikroslužby, IoT) se používají binární formáty:

| Formát | Použití |
| --- | --- |
| **Protocol Buffers (Protobuf)** | gRPC, Google ekosystém |
| **MessagePack** | "Binární JSON", menší a rychlejší |
| **CBOR** | IoT (RFC 8949) |
| **Apache Avro** | Big data, Kafka |
| **FlatBuffers** | Hry, real-time aplikace |

Tyto formáty nejsou lidsky čitelné, ale jsou výrazně menší a rychleji se parsují.

## 10 • HTTP stavové kódy pro REST

| Skupina | Význam |
| --- | --- |
| **1xx** | Informační |
| **2xx** | Úspěch |
| **3xx** | Přesměrování |
| **4xx** | Chyba klienta |
| **5xx** | Chyba serveru |

### Klíčové kódy pro REST API

| Kód | Proč |
| --- | --- |
| **200 OK** | GET/PUT/PATCH úspěšný s daty v odpovědi |
| **201 Created** | POST: záznam vytvořen, `Location` header s novou URL |
| **202 Accepted** | Request přijat, ale ještě se asynchronně zpracovává |
| **204 No Content** | Úspěch, ale žádná data (typicky DELETE) |
| **304 Not Modified** | Cache je stále platná (s ETag/If-None-Match) |
| **400 Bad Request** | Špatný formát, chybějící parametry |
| **401 Unauthorized** | Není přihlášen (nesprávný/žádný token) |
| **403 Forbidden** | Přihlášen, ale nemá oprávnění |
| **404 Not Found** | Zdroj neexistuje |
| **405 Method Not Allowed** | Tato metoda na tomto URL není povolená |
| 409 Conflict | Konflikt (duplicitní e-mail, edit race condition) |
| 410 Gone | Zdroj definitivně zmizel |
| 422 Unprocessable Entity | Syntakticky OK, ale validace selhala |
| **429 Too Many Requests** | Rate limiting, klient posílá moc |
| **500 Internal Server Error** | Něco se rozbilo na serveru |
| **502 Bad Gateway** | Upstream server neodpověděl správně |
| **503 Service Unavailable** | Server dočasně nedostupný |
| **504 Gateway Timeout** | Upstream timeout |

## 11 • Standardizovaný error response (Problem Details)

**RFC 9457** *(Problem Details for HTTP APIs)* definuje standardní strukturu chybové odpovědi:

```json
{
  "type": "https://example.com/errors/invalid-email",
  "title": "Neplatný e-mail",
  "status": 422,
  "detail": "E-mail 'foo@' nesplňuje formát.",
  "instance": "/users/create",
  "field": "email"
}
```

`Content-Type: application/problem+json`

Klient ví, jak chybu zpracovat: `type` jako strojový identifikátor, `title` pro uživatele, `detail` pro debug.

### Klasický error response (bez RFC)

```json
{
  "error": "InvalidInput",
  "message": "E-mail je povinný",
  "field": "email"
}
```

Většina API si dělá vlastní formát, ale konzistence napříč endpointy je klíčová.

## Ošetření chyb na klientovi

```jsx
async function fetchUser(id) {
  try {
    const response = await fetch(`/api/users/${id}`);

    if (!response.ok) {
      // Fetch nevyhodí pro 4xx/5xx automaticky
      const error = await response.json().catch(() => null);
      throw new ApiError(response.status, error?.message);
    }

    return await response.json();
  } catch (error) {
    if (error instanceof TypeError) {
      // Síťová chyba (no connection, DNS fail)
      console.error('Network error', error);
    }
    throw error;
  }
}

// Použití
try {
  const user = await fetchUser(42);
} catch (error) {
  if (error.status === 404) {
    showMessage('Uživatel neexistuje');
  } else if (error.status === 401) {
    redirectToLogin();
  } else {
    showMessage('Něco se pokazilo');
  }
}
```

### Retry logika

Pro idempotentní operace lze opakovat při dočasné chybě:

```jsx
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      if (response.ok) return response;
      if (response.status < 500) return response; // klient error, nemá smysl opakovat
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
    await new Promise(r => setTimeout(r, 2 ** i * 1000)); // exponential backoff
  }
}
```

# Bezpečnost REST API

| Princip | Detail |
| --- | --- |
| **HTTPS only** | Šifrování v přenosu, ověření identity serveru |
| **Autentizace** | JWT v `Authorization: Bearer <token>` headeru |
| **Autorizace** | Role-based access (RBAC), kontrolovat každý endpoint |
| **Rate limiting** | Limit requestů na IP/uživatele za čas |
| **CORS** | Omezit, kdo smí volat z prohlížeče |
| **Input validace** | Vždy validovat na serveru, klient může lhát |
| **No secrets in URL** | Hesla, tokeny patří do hlaviček nebo těla |
| **CSRF protekce** | Pro session-based auth, `SameSite` cookies |
| **API klíče** | Pro server-to-server, v `X-API-Key` headeru |

```bash
GET /api/users/me HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ...
X-API-Key: abc123def456
```

### Rate limiting hlavičky

Server typicky vrací informace o limitech:

```bash
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1717996400

# Při překročení:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
```

# Dokumentace API: OpenAPI / Swagger

**OpenAPI** (*Swagger)* je standardní formát pro **strojově čitelnou dokumentaci REST API**. Píšeš YAML nebo JSON, který popisuje endpointy, parametry, response schémata. Z toho se generuje:

- Interaktivní dokumentace (Swagger UI)
- Klientské SDK pro různé jazyky
- Test framework
- Mock server

```yaml
openapi: 3.0.0
info:
  title: Moje API
  version: 1.0.0
paths:
  /users/{id}:
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Uživatel
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          description: Neexistuje
```

# Alternativy k REST

### GraphQL

```graphql
query {
  user(id: 42) {
    name
    email
    posts(limit: 5) {
      title
      comments {
        text
      }
    }
  }
}
```

|  | REST | GraphQL |
| --- | --- | --- |
| **Endpoint** | Mnoho (`/users`, `/posts`) | Jeden (`/graphql`) |
| **HTTP metody** | GET/POST/PUT/DELETE | Vždy POST |
| **Data** | Server určuje, co vrátí | Klient si vybere fieldy |
| **Over-fetching** | Časté | Vyřešeno |
| **Under-fetching** | N+1 requesty | Vyřešeno (nested queries) |
| **Cache** | HTTP cache snadná | Komplikovanější |
| **File upload** | Nativní | Workaround (multipart, base64) |
| **Verzování** | Časté breaking changes | Deprecate fieldů, schema evoluce |
| **Dokumentace** | OpenAPI/Swagger | Automatická (introspekce) |

Použití: Facebook, GitHub, Shopify, Twitter. Vhodné pro komplexní UI s mnoha vztahy.

### gRPC

|  | REST | gRPC |
| --- | --- | --- |
| **Protokol** | HTTP/1.1 nebo /2 | HTTP/2 |
| **Formát** | JSON (text) | Protobuf (binární) |
| **Schéma** | OpenAPI (volitelné) | `.proto` soubor (povinné) |
| **Generování klientů** | OpenAPI generátory | Nativní |
| **Streaming** | SSE, WebSocket | Server, client, bidirectional |
| **Lidská čitelnost** | Ano (curl funguje) | Ne |
| **Použití** | Veřejné API, web | Mikroslužby, mobile-backend |

Použití: Google interní, Netflix, Uber.

### tRPC

TypeScript-only "RPC over HTTP" pro end-to-end type safety mezi backend a frontend. Pokud máš oba v TS (typicky Next.js full-stack), můžeš mít sdílené typy bez OpenAPI ceremonií.

### WebSocket / SSE

Pro **real-time** data (chat, live notifikace, sportovní výsledky):

- **WebSocket**: trvalé obousměrné spojení
- **Server-Sent Events (SSE)**: trvalý stream serveru ke klientovi, jednosměrný

<aside>
⚠️

NENÍ NÁHRADA (jinej purpose)! Spíš doplněk.

</aside>

# Tipy pro ústní zkoušku

### Jak začít

> *"REST je architektonický styl pro Web API, navržený Royem Fieldingem v roce 2000. Postaven nad HTTP, používá URL pro identifikaci zdrojů a HTTP metody pro operace (GET, POST, PUT, PATCH, DELETE). Data se typicky vyměňují v JSON. AJAX je klientská technika pro asynchronní komunikaci s API bez reloadu stránky."*
> 

### Co komise typicky chce slyšet

- **HTTP metody mapované na CRUD** (GET/POST/PUT/PATCH/DELETE).
- **Idempotence a bezpečnost metod** (GET bezpečná, POST ne).
- **JSON je standard, XML legacy.**
- **Stavové kódy** alespoň 200/201/204, 400/401/403/404, 500.
- **Stateless** princip a jak se řeší stav (token v hlavičce).
- **AJAX a Fetch API**, Promise stavy.

### Doplňky, které komisi potěší

- **6 architektonických omezení REST** (Fielding), ne jen 4.
- **Richardson Maturity Model** a kde dnešní API typicky jsou (Level 2).
- **Stránkování (cursor-based)** pro velké datasety.
- **Idempotency keys** pro retry-safe POST.
- **PATCH NENÍ obecně idempotentní** podle RFC 5789.
- **OpenAPI/Swagger** pro dokumentaci.
- **GraphQL jako alternativa** s konkrétními výhodami (over-fetching).

### Časté chytáky

| Otázka | Odpověď |
| --- | --- |
| *Rozdíl PUT a PATCH?* | PUT nahradí celý objekt, PATCH jen poslané fieldy. PUT je idempotentní, PATCH obvykle ne. |
| *Co znamená stateless v REST?* | Server si nepamatuje předchozí requesty. Každý request musí obsahovat vše potřebné (typicky token v hlavičce). |
| *Proč POST není idempotentní?* | Každé volání vytvoří nový záznam. Volání 3× = 3 nové záznamy. |
| *Co dělá `fetch`, když dostane 500?* | Promise se nerejectuje, vrátí response s `ok: false`. Musíš kontrolovat sám. (Axios na rozdíl vyhodí.) |
| *401 vs 403?* | 401 = nepřihlášen, 403 = přihlášen ale nesmí. |
| *Co je AJAX dnes?* | Termín z 2005 pro async komunikaci bez reloadu. Dnes se používá s JSON přes Fetch API. |
| *Proč nepoužít GET na smazání?* | GET je bezpečná = nemění stav. Crawlery/prefetchery ji volají automaticky, smazalo by ti to data. |