Skip to content

אידמפוטנטיות

יצירת משלוח היא קריאה בתשלום ובלתי הפיכה אל חברת השליחויות — כפילות פירושה חיוב אמיתי ומשלוח שני אמיתי. לכן endpoint היצירה של v2 (POST /shipments) אידמפוטנטי ועמיד לקריסות מעצם התכנון: בטוחים לניסיון חוזר, ובטוחים מפני קריסה באמצע בקשה, בלי לחייב את חברת השליחויות פעם נוספת לעולם.

כותרת ה-Idempotency-Key

שלחו כותרת Idempotency-Key אופציונלית בבקשת יצירה:

Idempotency-Key: 9c1a5f4e-2b6d-4a3e-8f10-7d0c2b3a4e5f

השתמשו בערך ייחודי וטרי (UUID הוא אידיאלי) לכל משלוח לוגי. אם אותה יצירה מנוסה שוב עם אותו מפתח, ה-API מחזיר את המשלוח המקורי במקום ליצור שני.

המפתח תחום לרישיון שנבחר עבורכם, והוא כבול לגוף הבקשה (ראו את כלל הקונפליקט בהמשך).

מה קורה בלי מפתח

הכותרת אופציונלית. כשמשמיטים אותה, ה-API גוזר טביעת אצבע של גוף הבקשה ומבצע דה-דופליקציה לפיה. טביעת האצבע מחושבת מהשדות שמגדירים את זהות המשלוח תחת הרישיון:

  • כיוון השירות (ship_data.type) ומצב ההחזרה (ship_data.return)
  • מזהה ההזמנה (order.id, עם נסיגה ל-order.number)
  • טלפון הנמען (ship_data.contact_phone)
  • היעד — ship_data.street, ship_data.number, ship_data.city ונקודת האיסוף (ship_data.pickup)
  • מספר החבילות (ship_data.packages)

שתי יצירות עם אותם ערכים בכל השדות הללו נחשבות לאותו משלוח ומאוחדות. שתי יצירות שנבדלות באחד מהם — למשל אותה הזמנה ואותו טלפון אבל כתובת שונה — נחשבות בצדק למשלוחים נפרדים ושתיהן עוברות.

טיפ

Idempotency-Key מפורש הוא המנגנון המדויק יותר. טביעת האצבע של הגוף היא רשת ביטחון ללקוחות שלא שולחים מפתח — אבל מכיוון שהיא מתעלמת משדות שמחוץ לקבוצת הזהות, העדיפו מפתח מפורש כשאתם זקוקים לסמנטיקת ניסיון-חוזר מדויקת.

ניסיון חוזר הוא בטוח

ביצירה, ה-API בודק תחילה אם קיימת תוצאה מושלמת שמורה במטמון עבור המפתח/טביעת האצבע הזו תחת הרישיון שלכם. אם קיימת, המשלוח המקורי מוחזר מיד — בלי נעילה, בלי קריאה לחברת השליחויות. ניסיונות חוזרים מקבילים מסודרים בנוסף מאחורי נעילה קצרה; אם יצירה זהה שנייה מגיעה בזמן שהראשונה עדיין בתהליך, היא לא יוצרת כפילות — היא מחזירה:

json
{
  "error": {
    "code": "duplicate_request",
    "message": "A shipment for this request is already being created. Please retry shortly.",
    "status": 409
  }
}

נסו שוב אחרי רגע ותקבלו את המשלוח שהושלם.

שימוש חוזר במפתח עם גוף שונה — 409 idempotency_key_conflict

Idempotency-Key כבול לגוף הבקשה המדויק של השימוש הראשון בו. שימוש חוזר באותו מפתח עם גוף שונה הוא שגיאת לקוח, לא החזרה שקטה של המשלוח הישן:

json
{
  "error": {
    "code": "idempotency_key_conflict",
    "message": "This Idempotency-Key was already used with a different request body.",
    "status": 409
  }
}

זה מגן עליכם מהסתרה בטעות של משלוח שונה באמת מאחורי מפתח ישן. כדי ליצור משלוח אחר, השתמשו במפתח חדש. (כבילת הגוף חלה רק כששולחים Idempotency-Key מפורש; לנתיב טביעת האצבע אין קונפליקט מקביל, כי זהות שונה פשוט מייצרת טביעת אצבע שונה.)

שחזור עמיד לקריסות — לעולם לא מחייבים את חברת השליחויות שוב

נתיב היצירה רושם את תוצאת חברת השליחויות לפני שמירת שורת המשלוח. הקריאה לחברת השליחויות היא הצעד בתשלום והבלתי הפיך, ולכן כתיבת תוצאתה למטמון תחילה מבטיחה שקריסה אחרי שחברת השליחויות הצליחה אבל לפני (או במהלך) השמירה המקומית לא תוכל לחייב את חברת השליחויות שוב בניסיון החוזר:

  1. הקריאה לחברת השליחויות מצליחה → קוד המעקב והתגובה הגולמית של חברת השליחויות נשמרים במטמון (עם מפתח האידמפוטנטיות / טביעת האצבע שלכם, תחת הרישיון שלכם) לפני שכל דבר נשמר.
  2. שורת המשלוח נשמרת, ואז ה-uuid שלה נכתב בחזרה לאותה רשומת מטמון.

אם קריסה קוטעת את הבקשה אחרי שלב 1, הניסיון החוזר הבא (מסודר תחת הנעילה) משחזר במקום לקרוא שוב לחברת השליחויות:

  • אם המשלוח אכן נשמר (רק כתיבת ה-uuid בחזרה אבדה), הוא מאותר לפי קוד המעקב השמור במטמון ונעשה בו שימוש חוזר — בלי שורה כפולה, בלי קריאה לחברת השליחויות.
  • אם השמירה מעולם לא התרחשה, שורת המשלוח נוצרת מחדש מתוצאת חברת השליחויות השמורה במטמון — ועדיין בלי קריאה שנייה לחברת השליחויות.

בכל מקרה, הניסיון החוזר מתכנס למשלוח היחיד שחברת השליחויות כבר יצרה. הרשומה השמורה חיה שעה אחת, וזה חלון השחזור לניסיון חוזר.

סיכום

מצבתוצאה
אותו מפתח (או אותה טביעת אצבע של גוף), הושלםמחזיר את המשלוח המקורי.
אותו מפתח, עדיין בתהליך409 duplicate_request — נסו שוב בעוד רגע.
אותו מפתח, גוף שונה409 idempotency_key_conflict.
מפתח שונה / זהות שונהיוצר משלוח חדש.
קריסה אחרי הצלחה אצל חברת השליחויותמשוחזר בניסיון החוזר בלי חיוב נוסף של חברת השליחויות.