Programování

Návrh REST API: URL, HTTP metody, status kódy a verzování

Praktická pravidla pro návrh REST API: pojmenování endpointů, správné HTTP status kódy, formát chyb, stránkování, idempotence a verzování.

12. 10. 2026 · 4 min čtení

Dobré API se pozná tak, že ho vývojář pochopí z pár příkladů a nemusí luštit dokumentaci. Tento článek shrnuje osvědčené konvence pro REST API nad HTTP – co dát do URL, jaký status kód vracet a jak API verzovat, aby změny nerozbily klienty.

URL jsou podstatná jména

Endpoint popisuje zdroj, akci určuje HTTP metoda:

Metoda a URL Význam
GET /orders seznam objednávek
POST /orders vytvoření objednávky
GET /orders/42 detail
PATCH /orders/42 částečná úprava
PUT /orders/42 nahrazení celého zdroje
DELETE /orders/42 smazání
GET /customers/7/orders objednávky zákazníka

Vyhněte se slovesům v URL (/getOrders, /createOrder). Výjimkou jsou akce, které se do CRUD nevejdou – pak je čitelné POST /orders/42/cancel.

Další konvence: množné číslo, malá písmena, slova oddělená pomlčkou (/payment-methods), vnoření maximálně o jednu úroveň.

Status kódy, které opravdu potřebujete

Úspěch (2xx)

  • 200 OK – běžná úspěšná odpověď s tělem.
  • 201 Created – po POST, který vytvořil zdroj. Přidejte hlavičku Location: /orders/43.
  • 202 Accepted – požadavek přijat, zpracuje se asynchronně (fronta).
  • 204 No Content – úspěch bez těla, typicky DELETE.

Chyby klienta (4xx)

  • 400 Bad Request – nevalidní JSON nebo chybná struktura požadavku.
  • 401 Unauthorized – chybí nebo je neplatné ověření (název je historicky zavádějící, jde o autentizaci).
  • 403 Forbidden – uživatel je známý, ale nemá oprávnění.
  • 404 Not Found – zdroj neexistuje. Lze použít i místo 403, pokud nechcete prozradit, že zdroj existuje.
  • 405 Method Not Allowed – metoda není pro endpoint podporována.
  • 409 Conflict – konflikt stavu: duplicitní e-mail, souběžná úprava.
  • 422 Unprocessable Content – syntakticky správný požadavek s neplatnými hodnotami (validace polí).
  • 429 Too Many Requests – překročený rate limit, ideálně s hlavičkou Retry-After.

Chyby serveru (5xx)

  • 500 Internal Server Error – neočekávaná chyba. Nikdy nevracejte stack trace klientovi.
  • 502 / 503 / 504 – problém upstreamu, údržba, timeout.

Nejhorší praxe: vracet 200 OK s tělem {"success": false}. Rozbíjí to cache, monitoring i HTTP klienty, kteří chyby rozpoznávají podle kódu.

Jednotný formát chyb

Existuje standard RFC 9457 (Problem Details, nahradil RFC 7807) s typem application/problem+json:

{
  "type": "https://api.example.cz/errors/validation",
  "title": "Neplatná data",
  "status": 422,
  "detail": "Některá pole nejsou vyplněna správně.",
  "errors": [
    { "field": "email", "message": "Neplatný formát e-mailu" }
  ]
}

Ať už standard použijete nebo ne, hlavní je, aby všechny endpointy vracely chyby ve stejném tvaru a se strojově čitelným kódem, na který může klient reagovat.

Stránkování, filtrování, řazení

GET /orders?status=paid&sort=-created_at&limit=20&cursor=eyJpZCI6MTAwfQ
  • Offset (?page=3&per_page=20) je jednoduchý, ale u velkých tabulek pomalý a při vkládání nových záznamů se položky posouvají.
  • Cursor (?cursor=...) odkazuje na poslední vrácený záznam, je stabilní a rychlý. Hodí se pro feedy a velké seznamy.

Odpověď:

{
  "data": [ { "id": 99, "status": "paid" } ],
  "next_cursor": "eyJpZCI6OTl9"
}

Vždy nastavte maximální limit, jinak si někdo stáhne celou tabulku jedním požadavkem.

Idempotence

GET, PUT a DELETE mají být idempotentní – opakované volání má stejný efekt jako jedno. POST není: když klientovi vypadne spojení a pošle požadavek znovu, vzniknou dvě objednávky.

Řešením je hlavička Idempotency-Key, kterou používá například Stripe:

POST /payments
Idempotency-Key: 3f1c9a2e-7b4d-4c1e-9a55-2d8f0e6b1c77

Server si klíč uloží s výsledkem a při opakování vrátí původní odpověď místo nového zpracování.

Verzování

Nejčastější a nejsrozumitelnější je verze v URL:

https://api.example.cz/v1/orders

Alternativy jsou hlavička (Accept: application/vnd.example.v2+json) nebo datum verze v hlavičce. Ty jsou „čistší“, ale hůř se ladí v prohlížeči a curlu.

Co je zpětně kompatibilní (nepotřebuje novou verzi):

  • přidání nového endpointu,
  • přidání nepovinného parametru,
  • přidání pole do odpovědi.

Co kompatibilitu rozbíjí:

  • odebrání nebo přejmenování pole,
  • změna typu ("id": 42 → "id": "42"),
  • nové povinné pole v požadavku,
  • změna významu status kódu.

Klienti by měli neznámá pole ignorovat. Starou verzi ohlaste dopředu a můžete použít hlavičky Deprecation a Sunset (RFC 8594).

Drobnosti, které dělají rozdíl

  • Časy ve formátu ISO 8601 s časovou zónou: 2026-10-12T14:30:00Z.
  • Konzistentní styl klíčů v JSONu – buď snake_case, nebo camelCase, ne obojí.
  • Částky v nejmenší jednotce (haléře) jako celé číslo, plus kód měny.
  • Pouze HTTPS.
  • Popis API ve formátu OpenAPI 3 – z něj vygenerujete dokumentaci i klienty.

Rychlá kontrola

curl -i -X POST https://api.example.cz/v1/orders \
  -H "Content-Type: application/json" \
  -d '{"customer_id": 7}'

Přepínač -i ukáže status kód i hlavičky. Pokud vytvoření vrátí 201 s Location, chybná data 422 se srozumitelnou chybou a neexistující ID 404, jste na dobré cestě.