Питання 6 · Розділ 6

Які HTTP методи ідемпотентні?

Ідемпотентні методи — це ті, які можна безпечно повторювати.

Мовні версії: English Russian Ukrainian

Junior Level

Ідемпотентні методи — це ті, які можна безпечно повторювати.

Ідемпотентні методи:

Метод Ідемпотентний Чому
GET Так Тільки читає дані, нічого не змінює
HEAD Так Як GET, тільки без тіла відповіді
OPTIONS Так Повертає інформацію про підтримувані методи
PUT Так Повна заміна ресурсу. Повтор = той самий результат
DELETE Так Перший видаляє, повторні підтверджують відсутність

Неідемпотентні методи:

Метод Ідемпотентний Чому
POST Ні Кожен виклик може створити новий ресурс
PATCH Залежить Залежить від того, що саме робить PATCH

Приклади:

GET /users/1      — ідемпотентний (читання)
PUT /users/1      — ідемпотентний (заміна)
DELETE /users/1   — ідемпотентний (видалення)
POST /users       — НЕ ідемпотентний (створення)

// GET ідемпотентний, тому що він тільки читає.
// PUT ідемпотентний, тому що замінює (замінив один раз — замінив другий раз на те саме).
// POST не ідемпотентний, тому що додає (додав один раз — додав ще раз = два об'єкти).

Middle Level

Безпечні (Safe) методи: GET, HEAD, OPTIONS

Вони ідемпотентні за визначенням, оскільки не повинні змінювати стан.

Важливо: Кешувальні сервери (Varnish, Cloudflare) можуть агресивно кешувати ці методи. Якщо зробити GET неідемпотентним (наприклад, інкрементує лічильник), кеш “сховає” зміни.

Змінюючі ідемпотентні методи: PUT, DELETE

  • PUT: Повна заміна. Якщо встановити status = 'ACTIVE' десять разів, статус залишиться 'ACTIVE'
  • DELETE: Видалення. Перший виклик видаляє, решта підтверджують відсутність

Чому POST не ідемпотентний?

POST зазвичай використовується для додавання в колекцію. 5 запитів POST /orders створять 5 замовлень. Через неідемпотентність POST не можна автоматично повторювати при мережевому тайм-ауті — це веде до проблеми “подвійних оплат”.

PATCH: “Залежить від реалізації”

  • {"op": "replace", "path": "/age", "value": 30} — ідемпотентний
  • {"op": "add", "path": "/tags", "value": "new"}не ідемпотентний (при повторі додасться ще один тег)
// `replace` завжди встановлює одне й те саме значення — повторний виклик безпечний.
// `add` додає елемент у колекцію — кожен повтор додає ще один.

Діагностика

  • 412 Precondition Failed: Використовується з If-Match для гарантії ідемпотентності PUT/PATCH
  • Завжди робіть два однакових виклики DELETE поспіль при тестуванні API

Senior Level

RFC 9110 і контракт інфраструктури

Ідемпотентність — це контракт між сервером і клієнтом, зафіксований у специфікації RFC 9110. На Senior-рівні важливо розуміти, як цей контракт впливає на поведінку інфраструктури (проксі, кеши, Service Mesh).

Роль у Service Mesh

Сучасні системи використовують Service Mesh (Istio, Linkerd) з функцією Automatic Retries:

  • Якщо ендпоінт позначено як ідемпотентний — меш автоматично перевідправляє запит при 503 або TCP Timeout
  • Якщо помилитися і метод POST буде автоматично повторений — отримаєте дублікати даних у БД
// Service Mesh (Istio) за замовчуванням повторює тільки GET, PUT, DELETE.
// POST вимагає явної анотації (наприклад, retryOn: retriable-4xx).

Продуктивність і Оптимізація

Idempotency Budget

У високонавантажених системах повтори можуть спричинити “шторм запитів” (Retry Storm). Якщо система лягла, а тисячі клієнтів почали повторювати ідемпотентні запити — вона не підніметься.

Рішення: Exponential Backoff і Jitter при повторах, навіть для ідемпотентних методів.

Edge Cases

Post-Incremental IDs

Якщо PUT /users/1 генерує пов’язані записи (аудит-лог з новими ID) — це не порушення ідемпотентності. Ідемпотентність стосується основного ресурсу. Внутрішні технічні ID або системні логи не ламають контракт.

Моніторинг

  • Metric: http_requests_retry_total: Сплеск повторів для неідемпотентних методів — сигнал про критичну помилку
  • Service Mesh конфігурація має чітко розрізняти ідемпотентні і неідемпотентні ендпоінти

🎯 Шпаргалка для співбесіди

Обов’язково знати:

  • Ідемпотентні: GET, HEAD, OPTIONS, PUT, DELETE
  • Неідемпотентні: POST (зазвичай), PATCH (залежить від реалізації)
  • Safe методи (GET, HEAD, OPTIONS) ідемпотентні за визначенням — вони не змінюють стан
  • PUT ідемпотентний: повна заміна ресурсу дає однаковий результат при повторі
  • DELETE ідемпотентний: після першого видалення ресурсу немає, повторні підтверджують відсутність
  • PATCH ідемпотентний тільки при детермінованих операціях (replace — так, add — ні)
  • Service Mesh (Istio) автоматично повторює тільки ідемпотентні запити при 503
  • Для POST з Idempotency Key у Service Mesh потрібна явна анотація retryOn

Часті уточнюючі запитання:

  • Чому POST не можна автоматично повторювати? — Ризик дублювання даних (подвійні оплати, замовлення)
  • Як Service Mesh використовує ідемпотентність? — Автоматично повторює GET/PUT/DELETE при 503, POST — тільки з явною конфігурацією
  • Що таке Retry Storm? — Шторм повторів: при падінні системи тисячі клієнтів одночасно повторюють запити
  • Чому ідемпотентність DELETE не порушується при генерації аудиту? — Ідемпотентність стосується основного ресурсу, а не побічних ефектів

Червоні прапорці (НЕ говорити):

  • «Усі HTTP методи ідемпотентні» — POST точно не ідемпотентний
  • «DELETE не ідемпотентний, тому що другий раз повертає 404» — стан сервера однаковий, це ідемпотентно
  • «PATCH завжди не ідемпотентний» — replace-операція ідемпотентна
  • «Ідемпотентність — це про код відповіді» — це про стан сервера

Пов’язані теми:

  • [[Що таке ідемпотентність (idempotency)]]
  • [[Чому GET та DELETE ідемпотентні]]
  • [[Чи є POST ідемпотентним]]
  • [[Які основні HTTP методи використовуються в REST]]
  • [[В чому різниця між PUT та PATCH]]