مفاهیم / Idempotency

Idempotency

از پرداخت‌های دوگانه در صورت قطعی شبکه یا تلاش مجدد جلوگیری می‌کند.

قرارداد

اندپوینت leads/get-records/ یک رشته idempotency_key الزامی دارد. این رشته باید UUID یکتا برای هر «نیت کاربر» باشد — نه برای هر تلاش http.

الگوی صحیح

  1. 1هنگام شروع یک عملیات (مثلاً «دریافت سرنخ‌های فیلتر فعلی برای کاربر X») یک UUID جدید بسازید.
  2. 2این UUID را در پایگاه داده محلی خود کنار اطلاعات عملیات ذخیره کنید.
  3. 3اگر درخواست به دلیل خطای شبکه یا timeout شکست خورد، با همان UUID درخواست را تکرار کنید — سرور یا تراکنش قبلی را برمی‌گرداند یا تراکنش جدید ایجاد می‌کند، بدون اینکه دو بار از کیف‌پول کسر شود.
  4. 4فقط زمانی که کاربر عملیات کاملاً جدیدی شروع می‌کند، UUID جدید بسازید.
javascript
// در شروع نیت کاربر، یک UUID بسازید و در DB ذخیره کنید
import { v4 as uuidv4 } from 'uuid'
const intent = {
filters: [{ key: 'gender', operand: 'equals', value: 2 }],
requested_fields: ['phone'],
idempotency_key: uuidv4(),
}
await db.intents.insert(intent)
// در صورت خطای شبکه، با همان کلید تلاش مجدد کنید
async function callWithRetry() {
for (let i = 0; i < 3; i++) {
try {
return await api.getRecords(intent)
} catch (err) {
if (err.code === 'ECONNRESET') continue
throw err
}
}
}

خطای 409 Conflict

اگر همان idempotency_key را با بدنه متفاوت ارسال کنید، سرور پاسخ 409 می‌دهد. این محافظ امنیتی است: یک کلید فقط به یک «نیت» تعلق دارد.