Идемпотентность. Как избежать повторных ошибочных вызовов операции?

Идемпотентность Mindbox

Mindbox API поддерживает разные типы вызовов: от передачи информации о просмотре страницы товара до расчета индивидуальной скидки для заказа клиента.

Для некоторых вызовов многократное повторение является нормальным. Например, клиент может несколько раз посмотреть одну и ту же страницу на сайте.

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

Mindbox поддерживает идемпотентность. Передача в вызове ключа идемпотентности позволит избежать повторного выполнения запроса. Дублирующий вызов с тем же ключом идемпотентности не будет обработан.
Если не передавать ключ идемпотентности, то каждый повторный вызов к API будет выполняться.

Примеры

Пример 1:

  • Клиент вызывает операцию с шагом "Отправить email" синхронно

  • Мы обрабатываем вызов, выполняем операцию, отправляем email и отвечаем через 5 секунд, что вызов успешно обработан.

  • Клиент не дождался ответа (таймаут клиента 2 секунды) и для надежности повторно вызывает операцию отправки этого же письма

  • Если ключ идемпотентности не использован, то клиенту отправится два одинаковых письма. При использовании ключа – одно, т.к. уже был успешно обработанный вызов и повторный был отброшен.

Пример 2:

  • Клиент вызывает операцию "Регистрации клиента" асинхронно
  • Мы ставим запрос в очередь и выполняем его
  • Клиент ошибочно еще раз вызывает операцию с этим же данными
  • Без ключа идемпотентности произойдет две регистрации. С ключом – только первая.

В итоге:

Если нет ключа идемпотентности, мы будем считать, что получили новый запрос и повторно выполним операцию.

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


Рассмотрим ситуацию, когда вы отправляйте вызов и обрабатывайте ответ от Mindbox (вызов выполнен успешно, мы вернули ошибку, либо вы не дождались ответа). Если операция завершилась с ошибкой следует повторно отправить этот же запрос. При этом важно использовать ключ идемпотентности.

Если первый запрос был выполнен, то повторный будет отброшен, т.к. содержит тот же ключ идемпотентности. Если первый запрос не был выполнен, то он будет обработан.

В синхронных вызовах при повторных запросах c повторяющимся ключом в ответ вернется статус TransactionAlreadyProcessed.

В асинхронных вызовах будет создана ошибка в логе выполненных операций: Транзакция с идентификатором {transactionId}={Id транзакции в вашей системе} уже была обработана.

Как создать ключ идемпотентности:

В Url операции добавить параметр transactionId с уникальным значением в виде GUID. transactionId - это стандартное имя ключа, GUID - это идентификатор специфического вида (например, cbcffb8e-aaf9-4e04-b3b6-1af8c9f77f16), этот формат обязателен, рекомендуется версия 4.

https://api.mindbox.ru/v3/operations/{sync/async}?endpointId={Идентификатор точки интеграции}&operation={Название операции}&transactionId=

Данный способ работает для всех асинхронных операций и для синхронных операций с шагом «Создать или обновить заказ».

Как использовать ключ идемпотентности

1. Для каждого отдельного запроса, т.е. запроса с разными данными, нужно создавать уникальный ключ идемпотентности.
2. Даже если вы вызываете разные операции с одним ключом идемпотентности, мы будем считать что это одни и те же данные и второй запрос с тем же ключом не будет выполнен.
3. Если вы хотите использовать свои внутренние ключи, которые уникальны только в рамках одной операции, то надо завести разные внешние идентификаторы для разных операций (например: orderTransactionId для оформления заказа и emailTransactionId для отправки рассылки).

Рекомендательные системы: что это и как работает алгоритм рекомендаций