Idempotency

Idempotent — операция, которую можно повторить N раз и результат будет как при однократном выполнении. Критично для сетевых API: клиент может retry-ить после таймаута, а сервер должен не задублировать эффект.

HTTP-методы

МетодIdempotent?Safe?
GETдада
HEADдада
OPTIONSдада
PUTданет
DELETEданет
POSTнетнет
PATCHзависитнет

Idempotency-Key header

Клиент генерит UUID перед POST. Шлёт как Idempotency-Key: uuid. При retry — тот же key.

POST /payments HTTP/1.1
Idempotency-Key: 07e5f210-...uuid
Content-Type: application/json

{"amount": 100, "to": "user_42"}

Логика на сервере

  1. Пришёл запрос с Idempotency-Key.
  2. Проверяешь: этот key уже видел?
  3. Да → вернуть сохранённый ответ (не выполнять повторно).
  4. Нет → выполнить, сохранить ответ + key на N дней.

Атомарность

Ключевой момент: сохранение key и выполнение операции должны быть атомарны. Иначе race: два параллельных retry могут оба увидеть "нет" и оба выполнить.

# SQL upsert-подход
INSERT INTO idempotency_keys (key, status) VALUES (?, 'processing')
ON CONFLICT (key) DO NOTHING RETURNING *;

# если RETURNING пусто — уже кто-то обрабатывает

TTL

Ключи не хранят вечно. Обычно 24 часа - 30 дней. Stripe — 24 часа. Достаточно для retry.

Кто использует

Natural idempotency

Иногда возможно без ключа: PUT (полная замена → повтор безопасен), DELETE (удалить дважды = удалить один раз).

Idempotency vs Deduplication

См. также

← на главную