Повторіть запит, не виконуючи роботу двічі

Заголовок Idempotency-Key — яким запитам він потрібен, чим відповідають на повторний запит і як вибрати ключ.

3 хв читання

Запит, який виконує флоу або рухає кредити, несе ваш власний ключ у заголовку Idempotency-Key. Ключ називає одну одиницю роботи. На запит, повторений з його ключем, відповідають, а не виконують його знову, тому повтор після тайм-ауту або втраченого з’єднання нічого не виконує двічі й нічого не списує двічі.

Де потрібен ключ

Заголовок обов’язковий для запитів, які щось витрачають або рухають:

  • запит, який виконує флоу, — POST /v1/operations/execute;

  • рух кредитів клієнта — POST /v1/customers/{externalUserId}/topup, POST /v1/customers/{externalUserId}/charge і POST /v1/customers/{externalUserId}/adjust.

Сторінка кожного ресурсу позначає ці операції. Решта операцій заголовок не читають.

  • Запит без заголовка або з порожнім заголовком відхиляється з 400 і кодом idempotency_key_required. Нічого не виконується.

  • Ключ — не довший за 190 символів. Довший відхиляється з 422 і кодом invalid_request — до того, як щось зарезервовано, списано чи нараховано.

Чим відповідають на повтор

Повтор — це той самий запит із тим самим ключем. Чим на нього відповідають, залежить від того, що зробив перший запит.

ЗапитПовтор з його ключем
Виконання флоуВиконання, яке відкрив перший запит, у тому стані, у якому воно перебуває в цей момент, із replayed, що дорівнює true: 202, поки виконання не закінчено, і 200 з його результатом, коли закінчено. Заново нічого не виконується
Рух кредитівПерша відповідь — протягом 24 годин. Після цього — рахунок у його теперішньому вигляді. Кредити рухаються один раз

Відповідь із помилкою в одних випадках зберігається, а в інших — ні.

  • Виконання флоу закріплює за собою ключ, щойно виконання з’явилося. Помилка, що надійшла до цього, — flow_not_found, тіло, яке не пройшло перевірку, — залишає ключ вільним. Помилка, що надійшла після, наприклад invalid_flow_input, закриває виконання, і повтор його читає: 200, статус failed і код.

  • Рух кредитів зберігає лише успішну відповідь. Відхилений запит можна надіслати ще раз із тим самим ключем.

Інший запит із зайнятим ключем

Ключ, який уже називає одиницю роботи, відхиляє іншу. Відповідь — 409 з кодом idempotency_conflict, і нічого не виконується.

409 Conflict
{
  "error": {
    "code": "idempotency_conflict",
    "message": "The Idempotency-Key was already used with a different request body",
    "request_id": "6b2e9c4a-1d7f-4e3b-8a5c-0f9d2e7b4c61"
  }
}

Що вважається іншим запитом, залежить від того, що називає ключ.

  • Для виконання флоу тіло порівнюється байт у байт. Інший вхід, інший context, інший execution_mode — і навіть ті самі поля в іншому порядку — дають інший запит.

  • Для руху кредитів будь-яке інше тіло — інший запит, поки зберігається перша відповідь. Після цього рух кредитів порівнюється за клієнтом, типом кредитів, видом руху й сумою.

Як вибрати ключ

  • Складайте ключ з одиниці роботи: замовлення та його крок (order-42:email) або ідентифікатор завдання вашої черги. Тоді кожен повтор цієї роботи несе той самий ключ, а наступна одиниця роботи отримує новий.

  • Ключ, створений випадково для кожної спроби, захищає лише цю спробу. Повтор, який ваш застосунок надсилає з новим ключем, — це нова робота, і за неї платять ще раз.

  • Ключ належить проєкту. Два проєкти можуть використовувати той самий ключ, а всередині проєкту кожна одиниця роботи має свій ключ.

  • Щоб виконати роботу знову після невдалого запиту — з іншим входом або іншою моделлю, — надішліть виправлений запит із новим ключем.

Що читати далі