מדריך פתרון תקלות ל-REST API של פריוריטי - למה שגיאות חוזרות כ-XML מ-API של JSON, מלכודת המפתח האוטומטי ב-PATCH, מגבלות אצווה, שילובי אימות שמבטלים זה את זה, ואיך למצוא את שמות השדות האמיתיים.
עיקרי הדברים
- שגיאות חוזרות כ-XML למרות שה-API הוא JSON. הטקסט השימושי נמצא בתוך אלמנט InterfaceErrors. אם הלקוח שלך מפרסר רק JSON, כל כשל ולידציה ייראה כמו שגיאת פרסור.
- אי אפשר לבצע PATCH לרשומה לפי המפתח האוטומטי שלה. יש להשתמש במפתח הייחודי הרגיל. זו שגיאה שמייצרת בשקט "רשומה לא נמצאה" על רשומות שבבירור קיימות.
- אימות Basic מפסיק לעבוד ברגע שמופעלת גישת External ID. אינטגרציה שרצה שנה יכולה להישבר משינוי תצורה בפריוריטי שאין לו קשר אליה.
- נקודת הקצה $metadata היא התשובה כמעט לכל שאלה מסוג "איך קוראים לשדה הזה". יש לקרוא אותה מההתקנה עצמה, כי טפסים ושדות מותאמים שונים בין אתרים.
ה-REST API של פריוריטי בנוי על OData ועובד היטב אחרי שמבינים אותו, אבל יש קבוצה קטנה של התנהגויות שגוזלות שעות בכל פרויקט ראשון. הרשימה הזו היא מה שכדאי לדעת לפני שמתחילים לנפות שגיאות, ולא אחרי.
לתכנון והערכת היקף של פרויקט אינטגרציה, ראה אינטגרציה מול ה-API של פריוריטי. לדחיפת אירועים החוצה במקום תשאול, ראה Webhooks בפריוריטי.
מבנה הכתובת - ומה נשבר בו
הכתובת הבסיסית היא:
https://<server>/odata/Priority/<tabula.ini>/<environment>/<FORM>שלושת המשתנים הם מקור לטעויות: tabula.ini הוא קובץ ה-tabula שבשימוש בהתקנה, ו-environment הוא השם הפנימי של החברה בפריוריטי - לא שם החברה כפי שהוא מוצג. שני אלה שונים בין לקוח ללקוח, ובין סביבת בדיקות לייצור אצל אותו לקוח.
הסקת הערכים האלה מניחוש היא בזבוז זמן. יש לבקש אותם מהאיש שמתחזק את ההתקנה.
השגיאה שמבלבלת הכי הרבה: XML מתוך API של JSON
אתה שולח JSON, מצפה ל-JSON, ומקבל בחזרה XML. שגיאות ולידציה חוזרות כאלמנט <FORM> שמכיל <InterfaceErrors>:
<InterfaceErrors>
<text>Specify 'N' or 'Y' as the default value...</text>
</InterfaceErrors>הבעיה המעשית: אם הלקוח שלך מנסה לפרסר כל תשובה כ-JSON, כל שגיאת ולידציה תיראה כמו שגיאת פרסור, וההודעה האמיתית - שהיא בדרך כלל מדויקת ומועילה - תיזרק לפח.
מה לעשות: לבדוק את סוג התוכן בתשובה, ואם היא אינה JSON - לחלץ את הטקסט מתוך InterfaceErrors ולתעד אותו כמות שהוא. זו ההודעה שתגיד לך בדיוק איזה שדה נדחה ולמה.
מפתחות: איפה זה נשבר
מפתח בודד ומפתח מורכב
רשומה מזוהה בסוגריים אחרי שם הישות:
GET /FAMILY_LOG('765')
GET /AINVOICES(IVNUM='T9696',IVTYPE='A',DEBIT='D')מפתח מורכב מפריד בין הרכיבים בפסיק, וכל רכיב מצוין בשמו. השמטת רכיב אחד לא תיתן שגיאה ברורה - היא פשוט לא תמצא את הרשומה.
המלכודת: PATCH לפי מפתח אוטומטי
זו כנראה השגיאה הכי מתסכלת בפרויקט ראשון. אי אפשר לעדכן רשומה לפי מפתח אוטומטי (auto-unique key). יש להשתמש במפתח הייחודי הרגיל.
למה זה מתסכל: ה-GET מחזיר לך את הרשומה עם המפתח האוטומטי בפנים, אתה משתמש בו ב-PATCH באופן טבעי לגמרי, והתוצאה היא כישלון שנראה כאילו הרשומה לא קיימת. אם אתה רואה "לא נמצא" על רשומה שאתה בדיוק קראת - זו כמעט תמיד הסיבה.
תת-טפסים
שורות בתת-טופס נכתבות דרך ניווט מהאב:
POST /ORDERS('SO18000002')/ORDERITEMS_SUBFORM
PATCH /ORDERS('SO18000002')/ORDERITEMS_SUBFORM(1)אפשר גם ליצור אב ובנים בבקשה אחת, על ידי הכללת מערך התת-טופס בגוף:
{
"CUSTNAME": "007",
"ORDERITEMS_SUBFORM": [
{ "PARTNAME": "111-001", "DUEDATE": "2016-08-01T00:00:00+03:00" }
]
}זו הדרך המומלצת ליצירת מסמך: בקשה אחת אטומית עדיפה על יצירת כותרת ואז שורות בקריאות נפרדות, כי כישלון באמצע משאיר מסמך חלקי במערכת.
אימות: שלוש שיטות ושילוב אחד אסור
| שיטה | פרטים |
|---|---|
| Basic | ברירת המחדל. שם משתמש וסיסמה של משתמש פריוריטי פעיל עם רישיון API, מתוך טופס תיק העובד. |
| Personal Access Token | מגרסה 19.1. מנוהל בטופס REST Interface Access Tokens, ומאפשר כמה טוקנים למשתמש. מוסר בשדות ה-Basic Auth, אבל מוסכמת שם המשתמש והסיסמה אינה אינטואיטיבית - לאמת בתיעוד העדכני. |
| OAuth2 | לגישה מצד שלישי או מהדפדפן. דורש רישיון מודול External ID, ומשתמש בכותרת Authorization: Bearer. |
השילוב האסור: אי אפשר להשתמש ב-Basic Authentication בזמן שגישת External ID מופעלת. זה חשוב לא רק בהקמה - זה אומר שהפעלת External ID בהתקנה, מסיבה שאין לה שום קשר אליך, תשבור אינטגרציה שרצה שנה. שווה לתעד את זה מול הלקוח.
נקודה נוספת: הרשאות המשתמש חלות על ה-API. אם משתמש ה-API לא רואה טופס בממשק, הוא לא יראה אותו גם דרך ה-API - וזה מתבטא כרשומות חסרות ולא כשגיאת הרשאה.
מגבלות שכדאי לדעת מראש
- גרסה מינימלית: ה-REST API זמין מפריוריטי 17.2 ומעלה.
- אצווה: עד 100 בקשות בקריאה אחת. בגרסאות שלפני 21.0 המגבלה הייתה 1,000. אם כתבת ייבוא שמסתמך על אצוות של 1,000 והלקוח שדרג - הוא נשבר.
- שמות שדות: אינם אינטואיטיביים ואינם זהים בין התקנות.
$metadata - הכלי שחוסך הכי הרבה זמן
נקודת הקצה /$metadata מחזירה את הסכימה המלאה של אותה התקנה: ישויות, שדות, טיפוסים וקשרים.
זה חשוב במיוחד בפריוריטי כי שדות וטפסים מותאמים אישית שונים בין אתרים. שני לקוחות על אותה גרסה יכולים לדרוש קוד אינטגרציה שונה לגמרי. כל תשובה שמצאת בפורום על שם שדה היא נכונה עבור ההתקנה של מי שכתב אותה, לא בהכרח שלך.
לכן: לפני שמנחשים שם שדה, למשוך את $metadata מההתקנה של הלקוח ולחפש בו. זו גם הדרך הנכונה לגלות אילו תת-טפסים קיימים ואיך הם נקראים.
סדר ניפוי שגיאות שעובד
- לוודא שהכתובת נכונה - במיוחד
tabula.iniושם הסביבה. - לבדוק שהמשתמש מחזיק רישיון API ורואה את הטופס בממשק.
- למשוך
$metadataולאמת את שם הישות ואת שמות השדות. - לבצע GET לרשומה בודדת לפני שמנסים לכתוב.
- אם כתיבה נכשלת - לקרוא את ה-XML. הטקסט ב-
InterfaceErrorsהוא כמעט תמיד ההסבר המדויק.
שאלות נפוצות
למה ה-REST API של פריוריטי מחזיר שגיאות ב-XML כששולחים JSON?
כשלי ולידציה מוחזרים כאלמנט FORM שמכיל InterfaceErrors, בפורמט XML, למרות שה-API מדבר JSON בכל השאר. אם לקוח ה-HTTP שלך מניח שכל תשובה היא JSON, הפרסור נכשל וטקסט השגיאה האמיתי נזרק. יש לבדוק את סוג התוכן בתשובות שגיאה ולחלץ את הטקסט מ-InterfaceErrors - הוא בדרך כלל מציין את השדה המדויק ואת הבעיה המדויקת.
למה PATCH מחזיר "לא נמצא" על רשומה שקיימת בפריוריטי?
רוב הסיכויים שאתה פונה לרשומה לפי המפתח האוטומטי שלה. ה-REST API של פריוריטי לא מאפשר עדכון לפי מפתח אוטומטי - יש להשתמש במפתח הייחודי הרגיל. הבלבול נובע מכך ש-GET מחזיר את הרשומה כשהמפתח האוטומטי בתוכה, ולכן השימוש בו ב-PATCH מרגיש טבעי.
כמה בקשות יכולה אצווה של פריוריטי להכיל?
עד 100 בקשות בקריאת אצווה אחת. בגרסאות שלפני 21.0 המגבלה הייתה 1,000, ולכן ייבוא שנכתב מול התקנה ישנה יכול להישבר אחרי שדרוג אצל הלקוח. כדאי לקבוע גודל אצווה של 100 או פחות ללא קשר לגרסה שאתה עובד מולה כרגע.
האם אפשר להשתמש באימות Basic מול ה-REST API של פריוריטי?
כן, זו שיטת ברירת המחדל, עם משתמש פריוריטי פעיל שמחזיק רישיון API. אבל היא מפסיקה לעבוד כשמופעלת גישת External ID בהתקנה - השתיים לא יכולות להתקיים יחד. מכיוון ש-External ID עשויה להיות מופעלת מסיבות שאין להן קשר אליך, זו תלות מתועדת ששווה להעלות מול הלקוח לפני העלייה לאוויר.
איך מוצאים את שמות השדות האמיתיים בהתקנת פריוריטי?
לבקש את נקודת הקצה /$metadata של אותה התקנה ספציפית. היא מחזירה את הסכימה המלאה - ישויות, שדות, טיפוסים וקשרים. זה חיוני בפריוריטי כי טפסים ושדות מותאמים שונים בין אתרים, ולכן שם שדה שעובד אצל לקוח אחד יכול לא להתקיים אצל אחר גם באותה גרסה.
מהי גרסת פריוריטי המינימלית ל-REST API?
פריוריטי 17.2. מתחת לזה ה-REST API אינו זמין ואינטגרציה נדרשת להשתמש במנגנון אחר, וזה הבדל מהותי בהיקף - ולכן כדאי לאמת את הגרסה המותקנת לפני שמתמחרים את העבודה.
להמשך קריאה
שירות רלוונטי
אינטגרציות
לגרום למערכות שאתם כבר משלמים עליהן לדבר זו עם זו.
על הכותב
יהונתן סעדיה
מהנדס פרילנסר לאוטומציה, אתרים ו-MVP
אני יהונתן סעדיה, מהנדס בכיר שבונה אוטומציה עסקית, אתרים מותאמים ומוצרי MVP לעסקים קטנים ובינוניים בארה"ב, אירופה וישראל. המדריכים האלה נכתבים מתוך עבודה אמיתית עם לקוחות, לא מתיאוריה.
בוא נעבוד יחדיש לך פרויקט דומה?
ספר לי מה אתה מנסה להפוך לאוטומטי או לבנות, ואומר לך מהי הדרך המהירה והאמינה ביותר ליישם את זה.
