🔁 Обеспечение идемпотентности API



Идемпотентная операция — это операция, которая при многократном вызове не меняет состояние ресурса. То есть, если мы повторно вызываем идемпотентный метод API, то не возникнет ошибок, связанных с дублированием одной и той же операции (например, двойных списаний баланса за один и тот же заказ).



По-хорошему, любой API должен быть идемпотентным.





Идемпотентность в REST API



HTTP-методы GET, PUT, DELETE формально считаются идемпотентными, тогда как POST и PATCH нет. Это не означает, что нельзя сделать GET неидемпотентным, а POST идемпотентным.



❗️ Важно: ответ идемпотентного метода может меняться. Например, при повторном вызове идемпотентного API создания заказа — заказ не будет создаваться ещё раз, но API может ответить как 200, так и 400. При обоих кодах ответа API будет идемпотентно с точки зрения состояния сервера (заказ один, с ним ничего не происходит), а с точки зрения клиента поведение существенно разное.





❗️ Проблемы неидемпотентных API



Проблема №1. Дублирование операций.

При сетевых задержках или ошибках одна и та же операция может быть выполнена несколько раз.



Пример с заказом такси:

1️⃣Пользователь вызывает такси в приложении

2️⃣Приложение отправляет запрос на создание заказа на сервер

3️⃣Возникает сбой, и приложение не получает успешный ответ по таймауту

4️⃣Приложение показывает сообщение «произошла ошибка» и делает кнопку заказа снова активной

5️⃣Пользователь снова нажимает кнопку

6️⃣К пользователю может приехать два такси вместо одного



Проблема №2. Неконсистентное состояние.

Неидемпотентные операции затрудняют отслеживание текущего состояния системы, что может привести к ошибкам и неконсистентности данных.



Пример с заказом такси:

1️⃣Пользователь изменяет пункт назначения в активном заказе такси через приложение.

2️⃣Приложение отправляет запрос PATCH /v1/orders/{id} на сервер для обновления заказа

3️⃣Возникает сбой, и приложение не получает подтверждение об успешном обновлении

4️⃣Приложение показывает пользователю сообщение об ошибке и предлагает повторить попытку

5️⃣Пользователь решает изменить пункт назначения на новый и снова отправляет запрос

6️⃣Сервер обрабатывает оба запроса: сначала второй, затем первый. В системе возникает неконсистентность: водитель видит один пункт назначения, а пользователь ожидает, что будет доставлен в другое место.





Идемпотентность создания и изменения



Способы обеспечения идемпотентности методов создания (POST) и частичного изменения (PATCH):

1. Ключ идемпотентности в заголовке запросов

2. Версионирование состояния

3. Блокировка на основе правил



🗝 Ключ идемпотентности



Это уникальный идентификатор операции, который помогает защититься от повторного исполнения операции.



Как это работает:

1. Клиент генерирует уникальный ключ идемпотентности и отправляет его в заголовке запроса. Например, Idempotency-Key: <UUID>

2. Сервер проверяет, был ли уже обработан запрос с таким ключом. Если да, возвращает результат предыдущего запроса, не выполняя операцию повторно. Иначе просто выполняет операцию.





⬇️ Продолжение ниже⬇️