הבאג שלימד אותי להפסיק להבדיל בין JSON כטקסט עלה לי רוב סוף השבוע. וו אינטרנט לתשלום ב-Laravel SaaS שאני מפעיל התחיל להיכשל בשקט אחרי ספק " non-breaking" עדכון API - המילים שלהם, מיומן השינויים. שלפתי מטען מלפני העדכון מהיומנים שלנו, תפסתי אחד טרי, וזרקתי את שניהם להפרש טקסט רגיל. כל שורה נדלקה. הספק החליף את הסידרה שלו, שסידר מחדש כל מפתח בסדר אלפביתי ושינה את ההזחה מארבעה רווחים למאתיים. שש מאות שינו שורות, ואיפשהו שם, הבדל אחד אמיתי. קראתי את ההבדל הזה מלמעלה למטה פעמיים לפני שמצאתי אותו: amount השתנה מהמספר 1099 אל המחרוזת "1099". אותם תווים על המסך. סוג אחר. ההשוואה הקפדנית שלנו דחתה את זה, התור ניסה את זה מחדש לתוך האדמה, והבדל הטקסט קבר את השינוי המשמעותי האחד תחת 599 קוסמטיים.
That's הבעיה הבסיסית: JSON הוא פורמט נתונים, אבל הבדל טקסט מתייחס אליו כאל פרוזה. סדר מפתח, רווח לבן, הזחה, שורות חדשות נגררות - אף אחד מהם לא אומר כלום למנתח JSON, וכל זה מופיע כשינויים בהשוואה מבוססת שורות. Per RFC 8259, אובייקט JSON הוא לא מסודר אוסף זוגות שם/ערך שני מסמכים יכולים להיות שונים בתים-עבור-בתים וזהים מבחינה סמנטית כלי שמשווה בין JSON שורה-שורה עונה על השאלה הלא נכונה.
א כלי הבדל JSON עונה על הנכון הוא מנתח את שני המסמכים לעצים ומשווה את ערכים: המפתח הזה נוסף, המפתח הזה הוסר, הערך הזה השתנה מ-X ל-Y, וזה שהציל את סוף השבוע שלי, לו היה קיים אז בכרטיסיית הדפדפן שלי - הערך הזה השתנה סוג. כאשר בניתי את בודק ההפרשים עבור Toolz.dev, זיהוי שינוי סוג היה התכונה הראשונה ברשימה, מכיוון שהוא ' זה מחלקת השינוי שמבחינה מבנית לא מסוגלים להופיע בטקסט וזה שובר מערכות אמיתיות לרוב.
מדריך זה מכסה כיצד פועלת השוואה מבנית, כאשר סדר מערך צריך וצריך' זה משנה, וזרימות העבודה של איתור באגים - רגרסיות API, סחיפה של תצורה, ביקורת גילוי חבילות - כאשר הבדל JSON משלם על עצמו מדי שבוע.
TL;DR: הדבק שני מסמכי JSON לתוך Toolz.dev JSON Diff Checker וקבל השוואה מבנית: הוספה, הסרה והחלפת מפתחות עם נתיבים מדויקים כמו
features.rateLimitאוusers[3].email- בתוספת סימון נפרד כאשר ערך משתנה סוג (ה3000→"3000"באג). סדר ועיצוב מפתח לעולם אינם מייצרים תוצאות חיוביות שגויות. הכל פועל בדפדפן שלך; שום דבר לא מועלה. חבר אותו עם ה פורמט JSON לנקות מסמכים קודם וה כלי Text Diff לתוכן שבו השורות חשובות בפועל.
מה זה אומר להבדיל בין JSON מבחינה מבנית?
הבדל מבני מנתח את שני המסמכים לתוך עצי הנתונים האמיתיים שלהם ומלווה אותם יחד, מפתח אחר מפתח, אלמנט אחר אלמנט. בכל צומת הוא שואל: האם המפתח הזה קיים משני הצדדים? האם הערכים זהים לסוג? האם הם שווים? הפלט הוא 't "line 14 changed" - it's רשימה של עובדות על הנתונים שלך:
versionהשתנה מ"1.4.0"ל"1.5.0"features.metricsנוספה עם ערךtrueportהשתנה סוג ממספר למחרוזתtags[2]נוספה עם ערך"monitored"
כל הבדל נושא את נתיב ה-JSON המלא שלו, כך שבמסמך מקונן עמוק אתה יודע בדיוק היכן לחפש. users[12].address.postalCode אומר לך איזה משתמש, איזה שדה, אין צורך בגלילה.
הניגוד עם הבדל טקסט הוא הבולט ביותר במסמכים בעולם האמיתי. קח א package.json שוחזר על ידי גרסת npm אחרת, תגובת API לאחר שצוות הקצה האחורי שדרג את הסיריאליזר שלו, או קובץ תצורה שרץ דרך מעצב. הבדל טקסט: מאות שורות שהשתנו הבדל מבני: שלושת השינויים שקרו בפועל, או התשובה הכנה שאין - "זהה מבחינה מבנית" - שהוא עצמו בעל ערך. אישור שיצר רפקטור מסוכן אפס שינויים בנתונים הם חצי מהסיבה שאני מגיע לכלי הזה.
There's מקום ל-line diffs, שיהיה ברור. פרוזה, קוד, HTML, כל דבר שבו פריסה פיזית נושאת משמעות - that's הבדל טקסט טֶרִיטוֹרִיָה. אבל לפריסה של JSON' אין משמעות לפי מפרט, והשוואה שמעמידה פנים אחרת מייצרת רעש, אז אתה צריך לסנן בעיניים.
מדוע שינויי סוג ראויים לקטגוריה משלהם?
כי הם ' הם בלתי נראים בכל תצוגה אחרת של הנתונים, והם שוברים דברים בדרכים שאומללות לנפות באגים.
1099 ו "1099" עיבוד זהה בקובץ יומן, במסוף וברוב הבדלי הטקסט - קל לפספס את הציטוטים ב-2 לפנות בוקר. אבל לכל צרכן מוקלד הם ערכים שונים. JavaScript's === דוחה את ההשוואה. סכמת JSON מצהירה "type": "integer" אימות נכשל. שירות Go unmarshalling לתוך int64 מחזירה שגיאה; מסיר ג'קסון קפדני ב-Java זורק. PHP הוא סלחן מפורסם עם השוואה רופפת, אבל ברגע שאתה מאפשר טיפוסים קפדניים - מה שכל בסיס קוד מודרני של Laravel צריך - "1099" מפסיק להיות כסף ומתחיל להיות חריג.
החלק המגעיל ביותר הוא איפה השינויים האלה מגיעים מ כמעט אף פעם לא ממפתח עורך ערך בכוונה הם מגיעים מהחלפות serializer, ORM שדרוגים, עמודת מסד נתונים נודדת מ INT ל VARCHAR, שכבת מטמון שמחרוזת מספרים, או שער API בעל כוונות טובות " מנרמל" מטענים. אף אחד לא כותב עבורם ערך יומן שינויים כי אף אחד לא יודע שהם קרו.
אז ה בודק הבדל JSON מדווח על שינויים מסוג כקטגוריה משלהם - ! בדוח הניתן להעתקה, להבדיל משינויי ערך רגילים - כשהסוגים הישנים והחדשים מאויתים. When you're בוהה בסיכום שאומר 0 added, 0 removed, 0 changed, 1 type changed, אתה יודע בדיוק איזה סוג של באג אתה ' צדים לפניך ' קראתם נתיב בודד.
כיצד ניתן להשוות שני קבצי JSON עם הכלי?
שלב 1: הדבק את שני המסמכים
מקורי (או ידוע-טוב) JSON הולך בלוח השמאלי, מעודכן (או חשוד) JSON בימין האמנה חשובה רק לקריאת הפלט: "added" פירושו נוכח מימין אך לא משמאל, "removed" פירושו הפוך. אם אתה ' משווים סביבת עבודה מול סביבת שבורה, שים עבודה משמאל וההבדל נקרא " מה שנשבר השתנה."
There' הוא כפתור טען מדגם המאכלס את שני הפאנלים בתצורת שירות קטנה המפעילה כל סוג הבדל - שינוי ערך, הוספה, שינוי סוג, צמיחת מערך - שזו הדרך המהירה ביותר ללמוד כיצד הפלט קורא.
שלב 2: החלט אם סדר מערך חשוב
זוהי האפשרות האחת שאתה צריך לחשוב עליה, והתשובה הנכונה תלויה במה שהמערכים שלך מתכוון- עוד על זה למטה ברירת המחדל היא רגישה לסדר, התואמת את מפרט JSON.Tick "התעלם מסדר מערך" כאשר המערכים שלך מוגדרים סמנטית.
שלב 3: השווה
שני המסמכים מאומתים לפני השוואה של משהו. אם לשני הצדדים יש שגיאת תחביר - פסיק נגרר, מרכאות בודדות, מפתח לא מצוטט, החשודים הרגילים - אתה מקבל את המנתח' הודעה מדויקת, ובאופן מכריע, איזה צד זה בא מ. No silent failure, no comparing half-parsed garbage.If you're not sure your JSON is even valid, run it through the פורמט JSON ראשון; זה מאמת ומדפיס יפה בשלב אחד.
שלב 4: קרא את הסיכום ולאחר מכן את הטבלה
שורת הסיכום נותנת לך ספירות לפי קטגוריה - הוספה, הסרה, שינוי, סוג שונה - וזה לעתים קרובות כל מה שאתה צריך. "47 נוסף, 0 הוסר, 0 השתנה" לאחר בליטה בגרסת API פירושו שדות חדשים בלבד: בטוח. "0 נוסף, 3 הוסר" פירושו שדות שהצרכנים שלך עשויים להיות תלויים בהם זה עתה נעלמו: לא בטוח. הטבלה שלהלן מפרטת כל הבדל עם הנתיב, הערך הישן והערך החדש שלו, קטוע לקריאה על ערכים ארוכים.
שלב 5: העתק את הדוח
כפתור העתק דוח מייצר סיכום טקסט רגיל עם + / - / ~ / ! סמנים ונתיבים מלאים - נועדו להדביק ישירות לתוך הערת בקשת משיכה, שרשור תקרית Slack או כרטיס. "Here's בדיוק מה השתנה בין הגדרת הבמה להפקה" עם קבלות, בלחיצה אחת.
מתי כדאי להתעלם מסדר מערך?
מערכי JSON מסודרים לפי מפרט - [1, 2] ו [2, 1] האם מסמכים שונים, והשוואת ברירת המחדל מכבדת זאת. אבל המפרט מתאר את המיכל, לא את הכוונה שלך, ובפועל נעשה שימוש במערכים בשתי דרכים שונות:
מערכים כרצפים, כאשר משמעות המיקום: שרשראות תווך הפועלות לפי הסדר, רשימות הגירה, לוחות הישגים ממוינים, תוצאות מעומדות. סידור מחדש של אלה הוא שינוי אמיתי - מחסנית תווך שפועלת auth לאחר handle הוא יישום שונה (וכנראה שבור) שמור על רגישות לסדר.
מערכים כסטים, כאשר המיקום הוא תאונה: רשימות תגים, הקצאות תפקידים, דגלי תכונה, מזהים שהוחזרו על ידי שאילתת מסד נתונים ללא ORDER BY. Postgres לגמרי בזכויותיה להחזיר את אותן שורות בסדר שונה בריצות שונות, ואם ההפרש שלך נדלק בגלל זה, הרעש הזה 's. זה מה שה-"התעלם מסדר מערך" האפשרות היא עבור - אלמנטים מותאמים ללא קשר למיקום, אז ["admin", "editor"] שווה ["editor", "admin"].
כלל האצבע שלי משנים של השוואת מטענים של API: אם הקצה האחורי מחיל מיון מפורש, התייחס למערך כאל רצף; אם זה 't, it's קבוצה בין אם המחברים הבינו זאת או לא, והשוואה לא רגישה לסדר אומרת לך את האמת על הנתונים.
הבדל מבני לעומת הבדל טקסט לעומת בדיקה ידנית
| הבדל JSON מבני | הבדל טקסט/קו | Eyeballing זה | |
|---|---|---|---|
| מקשים מסודרים | לא דווח על הבדל | כל קו שזז סומן | קל לפספס שינויים |
| רווח לבן מעוצב מחדש | לא דווח על הבדל | הכל סומן | N/A |
שינוי סוג (1 → "1") |
מסומן כשינוי סוג | שתי דמויות בים של שורות | כמעט בלתי נראה |
| מקונן לשנות מיקום | נתיב מדויק: a.b[2].c |
מספר שורה פנימה מעוצב טקסט | מעבר ידני |
| סדר מחדש של מערך (מכוון) | מסומן (או התעלם, הבחירה שלך) | מסומן | תלוי בגודל המערך |
| הטוב ביותר עבור | JSON, מטענים API, configs | קוד, פרוזה, סימון | מסמכים דו-שוריים |
| מצב כשל | אין על JSON חוקי | חיובי כוזב קוברים שינויים אמיתיים | עייפות אנושית |
הסיכום הכנה: text diffs aren't wrong, they're עונה על שאלה אחרת - "האם הבתים השתנו?" עבור JSON כמעט תמיד רצית "האם ה נתונים שינוי?", ולשאלות האלה יש תשובות שונות לעתים קרובות באופן מפתיע.
מהם זרימות העבודה בעולם האמיתי עבור הבדל JSON?
ריגרסיות API של ניפוי באגים
זרימת העבודה מסיפור ה-webhook שלי, כעת בשיטתיות: לכידת מטען מלפני השינוי (יומנים, מתקן מוקלט, חבילת הבדיקה שלך 's snapshot) ואחד מ- after. פאנל שמאלי, פאנל ימני, השווה. ההבדל אומר לך תוך שניות מה הספק 's changelog did't - אילו שדות זזו, איזה סוג שונה, שנעלם בשקט. אני עושה זאת בכל פעם שממשק API של צד שלישי מכריז על בליטת גרסה, לפני הגרסה הישנה שוקעת, ותייק את הדוח בכרטיס השדרוג.
תופס Config Drift
עבודות בימוי, הפקה does't, ושניהם היו "פרוסים מאותו config." היו? ייצוא שניהם - סביבה JSON, א docker inspect פלט, מפת Kubernetes ConfigMap שהושלכה עם -o json- וdiff אותם. Config drift הוא כמעט תמיד מקש אחד או שניים, ועמודת הנתיב לוקחת אותך ישר לשם. זה פועם diff <(jq -S . a.json) <(jq -S . b.json) בטרמינל כי הוא תופס גם שינויי סוג, אשר jq-הבדלי טקסט מנורמלים מציגים כמעט בלתי נראה.
סקירת שינויים בקובץ נעילה ומניפסט
א package.json או composer.json זה התבלבל על ידי מיזוגים סותרים, או מפרט OpenAPI שנוצר לאחר שדרוג מסגרת: הבדל מבני מראה לך את שינויי התלות ללא הרעש של העיצוב המחודש. לעבודת תוסף וורדפרס - WP Adminify שולח הגדרות כ-JSON - אני משנה את סכימת ההגדרות המיוצאות בין מהדורות כדי לוודא ש-refactor עשה ' t שחרר מפתח שאלפי התקנות תלויות בו. הסרה בשוגג מופיעה בתור א - קַו; בהפרש טקסט של ייצוא של 4,000 שורות זה מופיע כלא כלום.
אימות העברת נתונים
לפני: ייצוא רשומה מייצגת כ-JSON. לאחר ההגירה: ייצא אותו שוב. ההבדל צריך להראות בדיוק את השינויים שההגירה התכוונה ו שום דבר אחר. " זהה מבחינה מבנית" ברשומה שאמורה' לא נגעו בה היא מבחן הרגרסיה הזול ביותר שאתה ' אי פעם תרוץ. זה משתלב היטב עם המרת יצוא טבלאי דרך CSV ל-JSON כאשר הנתונים יוצאים ממסד הנתונים כ-CSV.
השוואת תגובות סביבתיות
הכה את אותה נקודת קצה בשתי סביבות, הבדל את התגובות שדות הקיימים ב-dev אך חסרים בייצור פירושם בדרך כלל דגל תכונה, פריסה מעופשת או משתנה סביבה שמעולם לא הוגדר. ספירת הסיכום לבדה מאבחנת זאת לעתים קרובות.
מדוע עיבוד צד הלקוח חשוב יותר עבור הכלי הזה מאשר לרוב?
תחשוב על מה שאתה מדביק לתוך הבדל JSON: תגובות API עם מיילים של לקוחות, קבצי תצורה עם שמות מארח פנימיים, מטענים של webhook עם מטא נתונים של תשלום, ייצוא מסד נתונים זה בדיוק הנתונים שאסור לדלוף, מודבקים בדיוק ברגע - אמצע האירוע - כאשר אף אחד לא מבקר איזה כלי מקוון בדיוק קיבל אותו.
ה בודק diff Toolz.dev מנתח ומשווה לחלוטין בדפדפן שלך אין בקשה נושאת את המסמכים שלך בכל מקום; הכלי עובד במצב לא מקוון לאחר טעינת הדף, שאותו תוכל לאמת על ידי חיתוך הרשת שלך והשוואה שוב. This is 't תכונת פרימיום או הבטחת מדיניות שעלולה להשתנות - it's הארכיטקטורה. לוגיקת ההשוואה היא JavaScript טהור הפועלת על שני עצים מנותחים בזיכרון. אין רכיב שרת לשלוח אליו נתונים.
אותו טיעון פרטיות חל על כל ארגז הכלים - it' הסיבה לכך מפתח ערכת כלים על Toolz.dev בנוי ראשון בדפדפן - אבל כלי הבדל הם המקום שבו זה 's החריף ביותר, כי השוואה שתיים מסמכי הפקה מכפילים את החשיפה של הדבקת אחד.
כמה גדול מסמך אתה יכול להשוות?
ההשוואה מבקרת בכל צומת בשני העצים פעם אחת, כך שהעבודה מתרחבת באופן ליניארי עם גודל המסמך. בפועל: מסמכים במאות קילובייט משתווים באופן מיידי; מגה-בייט חד ספרתי נמוך משלימים הרבה פחות משנייה בכל דבר שדומה למחשב נייד מודרני; עשרות מגה-בייט יעבדו אבל אתה ' תרגיש את זה, מכיוון שהדפדפן צריך לנתח את שני המסמכים ולהחזיק את שני העצים בזיכרון בו זמנית.
שני טיפים מעשיים למטענים גדולים מאוד ראשית, אם אכפת לך רק מחלק מהמסמך, השווה רק את תת העץ הזה - הדבק response.data.items משני הצדדים ולא מהמעטפה המלאה. שנית, אם ההבדל מייצר אלפי ערכים, זה ' זה בדרך כלל סימן שצד אחד שונה צורה (מערך עטוף בחפץ, רמת קינון נוספת) - בדוק את השבילים הראשונים לפני הגלילה; הם' יגידו לך אם אתה' מסתכלים על שינוי מבני אחד מדורג או אלפי אמיתי.
שָׁוא
כיצד אוכל להשוות שני קבצי JSON באינטרנט?
פתח את בודק הבדל JSON, הדבק מסמך אחד בחלונית השמאלית והשני בימין, ולחץ על השווה. אתה מקבל רשימה מסווגת של כל ערך שנוסף, הוסר, השתנה ושונה סוג עם נתיב ה-JSON המדויק שלו. שני המסמכים מעובדים במלואם בדפדפן שלך - שום דבר לא מועלה לאף שרת.
מדוע הבדל טקסט מראה כל כך הרבה שינויים כאשר נתוני ה-JSON שלי זהים?
מכיוון שהפרשי טקסט משווים שורות, ו-JSON מאפשר לכתוב את אותם נתונים בדרכים רבות. מפתחות מסודרים מחדש, הזחה שונה ורווח לבן משנים כולם את הטקסט מבלי לשנות את הנתונים. הבדל מבני מנתח תחילה את שני המסמכים ומשווה ערכים בפועל, כך שהבדלי עיצוב מייצרים אפס שינויים מדווחים.
האם סדר המפתחות באובייקט JSON משנה?
מס' RFC 8259 מגדיר אובייקט JSON כאוסף לא מסודר של צמדי שם/ערך, אז {"a":1,"b":2} ו {"b":2,"a":1} האם אותו אובייקט בודק הדיפים משווה אובייקטים לפי שם מפתח ולעולם לא מדווח על סדר מחדש כשינוי סדר רכיבי מערך, לעומת זאת, הוא משמעותי כברירת מחדל - מערכים מסודרים במפרט.
מתי עלי להשתמש ב-"התעלם מסדר מערך" אוֹפְּצִיָה?
השתמש בו כאשר המערכים שלך הם סטים סמנטיים ולא רצפים - רשימות תגים, אוספי תפקידים, מזהים משאילתת מסד נתונים לא ממוינת. עם האפשרות פועלת, [1,2,3] ו [3,1,2] השווה כשווה השאר את זה כאשר המיקום נושא משמעות, כמו שרשראות תווך מסודרות, תוצאות מדורגות או רשימות מעומדות.
מהו שינוי סוג ומדוע הוא מסומן בנפרד?
שינוי סוג הוא כאשר ערך 's סוג JSON שונה בין מסמכים גם אם הוא נראה דומה - המספר 3000 הופכים למחרוזת "3000" הוא המקרה הקלאסי. It's מסומן בנפרד מכיוון שהוא שובר צרכנים מוקפדים, אימות סכימה ובדיקות שוויון קפדניות תוך שהוא כמעט בלתי נראה בהפרשי טקסט ויומנים. It' הוא אחד הגורמים הנפוצים ביותר לרגרסיות אינטגרציה של API.
האם אוכל לשתף את תוצאת ההשוואה עם הצוות שלי?
כן. כפתור העתק דוח יוצר דוח הבדל בטקסט רגיל עם + (נוסף), - (הוסר), ~ (שונה), ו ! (סוג השתנה) סמנים ונתיבי JSON מלאים לכל הבדל. It's מעוצבים להדבקה נקייה לתוך הערות בקשת משיכה, שרשורים רפויים ועוקבי בעיות.
האם זה בטוח להדביק תגובות API ייצור לתוך הכלי?
כן. ניתוח והשוואה פועלים במלואם ב-JavaScript בדפדפן שלך - לא מתבצעת בקשת רשת עם הנתונים שלך, שום דבר לא נרשם או מאוחסן, והכלי ממשיך לעבוד במצב לא מקוון. זה הופך אותו לבטוח עבור מטענים המכילים נתוני לקוחות, שמות מארח פנימיים או אישורים, אם כי עורך סודות לפני שיתוף דיווח עדיין עליך.
מה קורה אם אחד מהמסמכים שלי הוא 't תקף JSON?
הכלי מאמת את שני הצדדים לפני השוואה ומדווח על המנתח's הודעת שגיאה מדויקת יחד עם מאיזה צד הוא הגיע - משמאל או מימין. אשמים נפוצים הם פסיקים נגררים, מרכאות בודדות במקום כפולות ומפתחות לא מצוטטים. תקן את הבעיה המדווחת, או הפעל את המסמך דרך פורמט JSON כדי לאתר את הבעיה, אז השווה שוב.
השוואה מבנית היא אחד מאותם כלים שמשנים אילו באגים אתה יכול אפילו לראות. טקסט שונה תשובה "האם הבתים השתנו?"; עבור JSON, השאלה החשובה היא " האם הנתונים השתנו?" - ועבור המטענים, ההגדרות והמניפסטים של ה-API שמריצים את המערכות שלך, ה בודק הבדל JSON עונה על זה תוך שניות, בדפדפן שלך, כשהנתונים שלך לעולם לא עוזבים את המחשב שלך. זרימות עבודה נוספות של JSON - עיצוב, אימות, המרה - חיות ב- מדריך כלי קידוד.



