عدم التكرار وإعادة المحاولة
يجب أن يحمل كل طلب وقت فعلي Idempotency-Key. وهو ليس مجاملة لحدود المعدّل — بل هو ما يجعل إعادة المحاولة آمنة. فالشبكات تفشل بعد أن يكون قد طُلب من المورّد بالفعل؛ ودون مفتاح، تكون الطريقة الوحيدة لمعرفة ما إذا كان الفحص قد نُفّذ هي تنفيذه مجددًا والدفع مرتين.
القاعدة
Section titled “القاعدة”أرسل قيمة يمكنك توليدها مجددًا: UUID، أو معرّف طلب، أو تجزئة للعمل الذي تقوم به. ويحصرها الخادم في حسابك، فلا يمكن أن يتصادم مستخدمان.
| المفتاح نفسه | الحمولة | النتيجة |
|---|---|---|
| مفتاح جديد | أي | يُنفَّذ عادةً، ويُحتسب |
| المفتاح نفسه | مطابقة | تُرجع الاستجابة المخزّنة؛ مع replayed=true. لا احتساب جديد. |
| المفتاح نفسه | مختلفة | 409 idempotency_conflict — المفتاح مرتبط بالحمولة التي حملها أول مرة |
| المفتاح نفسه | مطابقة، وأول طلب لا يزال قيد التنفيذ | 409 request_in_progress مع Retry-After |
Idempotency-Key محدود بـ 191 بايت وتُحتفظ بسجلات الإعادة لمدة 30 يومًا افتراضيًا.
replayed ليس cached
Section titled “replayed ليس cached”يبدوان متشابهين في الاستجابة ويعنيان شيئين مختلفين:
| الحقل | الموضع | المعنى |
|---|---|---|
replayed | المستوى الأعلى | لم يصل هذا الطلب إلى المورّد أبدًا — فقد أعدت استخدام مفتاح. |
cached | داخل كل نتيجة | قُدِّم حكم هذا المنتج من ذاكرة النتائج المؤقتة. |
يعيد الطلب المُعاد إنتاج الاستجابة الأصلية، بما في ذلك قيمة cached لكل مدخل. ولا يغيّر أي من العلمين ما احتُسب عليك: فالإعادة لا تحرّك أي مبلغ، وإصابة الذاكرة المؤقتة تُحتسب أيضًا بسعر المنتج لكل فحص.
لا تُخزَّن كوقائع إلا النتائج المسوّاة. النتائج الفاشلة ونتائج unknown لا تُخزَّن مؤقتًا — فالفحص اللاحق للمعرّف نفسه مقابل المنتج نفسه سيسأل المورّد مجددًا بدلًا من إعادة إجابة غير حاسمة.
إعادة المحاولة بعد فشل
Section titled “إعادة المحاولة بعد فشل”| ما رأيته | ما يجب فعله |
|---|---|
| مهلة، أو HTTP 500 | أعد إرسال المتن الأصلي بـالمفتاح الأصلي. النتيجة غير مؤكدة؛ وهذه هي الحالة التي يوجد المفتاح من أجلها. |
409 request_in_progress | انتظر Retry-After، ثم أعد إرسال المتن نفسه بالمفتاح نفسه. |
409 idempotency_conflict | المفتاح يحمل بالفعل حمولة مختلفة. ولّد مفتاحًا جديدًا — لا تعدّل المتن وتعيد استخدام المفتاح القديم. |
429 realtime_rate_limited | انتظر Retry-After. لم يُرسل شيء، لذا لا يزال المفتاح نفسه غير مستخدم وآمنًا للإرسال. |
503 realtime_route_unavailable | لم يُرسل شيء. أعد المحاولة لاحقًا بالمفتاح نفسه. |
الشيء الوحيد الذي يجب ألا تفعله أبدًا بعد مهلة هو إرسال مفتاح جديد بالعمل نفسه: فإذا كان الطلب الأول قد وصل فعلًا، فأنت قد دفعت للفحص مرتين.
الأخطاء التي تُرفع هنا
Section titled “الأخطاء التي تُرفع هنا”| HTTP | code |
|---|---|
| 400 | idempotency_key_required — الترويسة مفقودة |
| 409 | request_in_progress — الطلب الأصلي لا يزال قيد التنفيذ |
| 409 | idempotency_conflict — استُخدم المفتاح أول مرة بحمولة مختلفة |