Назад к подготовке

Идемпотентность endpoint-а пополнения баланса

Пользователь повторно отправил запрос на пополнение баланса. Как сделать endpoint идемпотентным?

Ответить самому

Сначала сформулируйте ответ как на собеседовании, затем откройте разбор и оцените себя.

Загрузка

Короткий ответ

Клиент присылает idempotency key, сервер хранит результат первого выполнения и при повторе возвращает тот же результат, не меняя баланс второй раз.

Полный разбор

Для операции с деньгами retry неизбежен: клиент мог не получить ответ, сеть оборвалась, gateway повторил запрос. Поэтому логический запрос должен иметь idempotency key. Сервер в транзакции проверяет, был ли такой key для этого пользователя/операции.

Если key новый, сервер выполняет операцию, записывает изменение баланса и сохраняет результат: status, operation id, amount, response payload. Если key уже был, сервер не делает новое начисление, а возвращает сохраненный результат. Важно ограничить scope ключа, например user_id + operation_type + key, и хранить TTL.

Нужны уникальный индекс в БД, транзакции, защита от concurrent duplicate requests и понятная обработка intermediate state: если первая попытка зависла, повтор должен либо дождаться результата, либо вернуть retryable статус без двойного списания/начисления.

Теория

Идемпотентность делает повтор одного логического запроса безопасным для состояния системы.

Типичные ошибки

  • Генерировать idempotency key на сервере после получения запроса.
  • Проверять дубликат вне транзакции без unique constraint.
  • Не сохранять response первого выполнения.