Безопасные повторы HTTP-запросов и идемпотентность
Сетевой таймаут не доказывает, что сервер ничего не сделал. Повтор изменяющего запрос без проверки способен выполнить операцию дважды.
Главное за минуту
- Автоматически повторяйте только операции с известной идемпотентностью.
- Для платных действий нужен стабильный ключ и postcheck.
- Политика повтора задаётся для каждого endpoint отдельно.
- Один ключ не может использоваться с разными параметрами.
Семантика метода
RFC определяет safe и idempotent свойства методов. Но реальная безопасность зависит также от контракта конкретного API и реализации ресурса.
Составьте каталог endpoints с полями effect, retryPolicy и reconciliationMethod. GET не должен скрыто запускать изменение состояния; POST по умолчанию считайте небезопасным для автоматического повтора. PUT и DELETE могут быть идемпотентными по намерению, но клиент всё равно должен учитывать побочные платежи, webhooks и ограничения конкретного контракта API.
Неизвестный результат
Если ответ потерян после отправки команды, сохраните состояние outcome_unknown и сначала запросите фактический объект, платёж или статус команды.
Состояние outcome_unknown блокирует новую конкурирующую операцию только для того же объекта. Worker запрашивает заказ, платёж или оборудование по стабильному идентификатору и сравнивает ожидаемые поля. Если поставщик не предоставляет достоверного postcheck, задачу переводят на ручную сверку; автоматическое повторение внешней команды запрещают.
Ключ идемпотентности
Один пользовательский замысел получает один стабильный ключ. Сервер хранит результат и возвращает его при повторе, не создавая второй эффект.
Ключ формируйте на стороне клиента один раз и сохраняйте вместе с замыслом пользователя: тип, объект, сумма и количество. Сервер должен атомарно закрепить ключ до побочного эффекта и вернуть прежний результат при повторе. Нельзя создавать новый ключ после обновления страницы, если пользователь не подтвердил новую самостоятельную операцию.
Повтор после 429
Даже безопасный запрос следует повторять с паузой и пределом попыток. Для небезопасного запроса сначала подтверждают, что он не был применён.
Метрики должны показывать число повторов, cache hits по идемпотентному ключу, outcome_unknown, время сверки и ручные решения. Отдельный алерт нужен, если один ключ связан с разными параметрами — это конфликт клиента или атака. В ответ возвращайте безопасную ошибку без раскрытия данных исходной операции другому пользователю.
Практический чек-лист
- 1Классифицируйте каждую команду по эффекту.
- 2Добавьте идемпотентный ключ.
- 3Предусмотрите outcome_unknown и ручную сверку.
- 4Создайте каталог effect и reconciliationMethod.
- 5Алертите конфликт параметров одного ключа.
Источники и документы
Материал подготовлен по первичным, официальным и техническим источникам. Формулировки статьи являются самостоятельным изложением.