Какие HTTP методы идемпотентны?
Идемпотентные методы — это те, которые можно безопасно повторять.
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]]