דלג לתוכן הראשי

developer-tools

YAML מול JSON מול TOML: מתי להשתמש בכל פורמט הגדרות

robinhood-projectsקריאה של 11 דקות

JSON Viewer, Formatter & Editor

צפה, ערוך ועצב JSON בעץ אינטראקטיבי חי. עריכת ערכים inline, שינוי שם מפתחות, הוספה/הסרה של צמתים, תמיכה בהערות JSONC וייצוא בלחיצה אחת — הכל בדפדפן שלך.

השתמש בכלי ←

צופה CSV ושולחן חכם

פתח כל קובץ CSV כטבלה אינטראקטיבית חכמה: מיין עמודות, סנן שורות, ערוך תאים בזמן אמת וייצא ל-CSV, XLS או XLSX. הכול בדפדפן, ללא הרשמה.

השתמש בכלי ←

YAML מול JSON מול TOML: מתי להשתמש בכל פורמט הגדרות

כל פרויקט נתקל בסופו של דבר בבעיית הגדרות. צריך לאחסן נתוני גישה למסד נתונים, להגדיר סביבות פריסה, לתאר צינור CI, או לחבר תלויות — ומישהו חייב לבחור פורמט. JSON? YAML? TOML? הבחירה נראית שרירותית עד שהיא נושכת.

קבצי Docker Compose הם YAML. package.json הוא JSON. מניפסט התלויות של Rust (Cargo.toml) הוא TOML. אריזת Python (pyproject.toml) היא TOML. תהליכי עבודה של GitHub Actions הם YAML. זה לא מקרי — כל פורמט זכה בקרב האימוץ בתחומו מסיבות ספציפיות. הבנת הסיבות הללו מאפשרת לקבל החלטה מושכלת במקום לברירת המחדל של "מה שהתבנית השתמשה בו".

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


האב המשותף: קבצי INI

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

קבצי INI נראים כך:

[database]
host = localhost
port = 5432
name = mydb
 
[server]
port = 8080
debug = true

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

INI היה בסדר עבור php.ini ב-1997. הוא לא בסדר לתיאור פריסת Kubernetes ב-2026. אך הוא זיהה את המטרות הנכונות — עריכה על ידי אדם ותגובות — שהפורמטים המודרניים או ירשו או נטשו.


JSON: ה-Lingua Franca של הנתונים

JSON (JavaScript Object Notation) עבר תקינה בתחילת שנות ה-2000 והפך לפורמט התקשורת הדומיננטי עבור APIs. כוחו נובע מהמגבלות שלו.

מה JSON עושה נכון

ל-JSON יש בדיוק שישה סוגי ערכים: מחרוזת, מספר, בוליאני, null, מערך ואובייקט. המפרט חד-משמעי. כל מנתח JSON תואם יפרש את אותה מסמך באופן זהה. אין הפתעות.

{
  "database": {
    "host": "localhost",
    "port": 5432,
    "ssl": true
  },
  "allowed_origins": ["https://example.com", "https://api.example.com"],
  "timeout_ms": null
}

הסוג של port הוא מספר ללא ספק. ssl הוא בוליאני ללא ספק. allowed_origins הוא מערך של מחרוזות ללא ספק. מנתח JSON לא יכול לקרוא זאת בצורה שגויה.

JSON גם נפוץ בכל מקום. לכל שפת תכנות יש מנתח JSON בספריה הסטנדרטית. דפדפנים מפרשים אותו מקומית. מסדי נתונים כמו PostgreSQL מכילים עמודות JSON מקוריות. זהו פורמט המכנה המשותף הנמוך ביותר לחילופי נתונים בין מערכות שאינן חולקות סביבת ריצה.

מה JSON מחטיא בהגדרות

ל-JSON אין תחביר להערות. זוהי החלטת עיצוב מכוונת של Douglas Crockford (יוצר JSON), בטענה שהערות בפורמטי נתונים מעודדות אנשים לשים בהם הוראות ניתוח, מה שמחבל בניידות הפורמט.

זה עיקרון סביר עבור תגובות API. זו בעיה רצינית עבור קבצי הגדרות. קבצי הגדרות צריכים הערות. צריך להסביר מדוע timeout_ms הוא 30000 ולא 10000. צריך לסמן אילו שדות בטוחים לשינוי. צריך להשאיר הערה שאומרת "אל תגדיר זאת מעל 100 בסביבת staging".

הפתרונות החלופיים כולם גרועים. חלק מהצוותים משתמשים בשדות "_comment". חלקם משתמשים ב-JSON5 (על-קבוצה עם הערות) ומקווים שהכלים שלהם מתמודדים איתה. חלקם משתמשים ב-JSONC (JSON עם הערות, שהתפרסם עם settings.json של VS Code). אף אחד מאלה אינו JSON סטנדרטי.

JSON גם מפורט להגדרות. פסיקים מסיימים אינם מותרים, מה שגורם לשגיאות תחביר מתמשכות בעת סידור מחדש של שדות. כל מפתח מחרוזת דורש מרכאות כפולות. אין תחביר למחרוזות מרובות שורות — פקודת shell ארוכה חייבת להיות מוחלפת לשורה אחת.

JSON שייך ב: תגובות API, חילופי נתונים בין שירותים, מניפסטים של חבילות שנכתבות בעיקר על ידי מכונות (package.json, composer.json), ובכל מקום שצריך עקביות ניתוח מובטחת על פני מערכות הטרוגניות.

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


YAML: כוח וסכנה

YAML (YAML Ain't Markup Language) תוכנן להיות החלופה הידידותית לאדם של XML. הוא ביטויי, קריא, ומשמש רבות בכלי DevOps. הוא גם פורמט ההגדרות המסוכן ביותר בשימוש נפוץ.

מה YAML עושה נכון

YAML מאפשר הערות (#). הוא מסיק סוגים מערכים ללא מרכאות, כך שאפשר לכתוב port: 5432 במקום "port": 5432. הוא תומך במחרוזות מרובות שורות עם תחביר נקי דמוי heredoc. הוא תמציתי: הזחה מחליפה סוגריים מסולסלים ורגילים.

database:
  host: localhost
  port: 5432
  ssl: true
 
allowed_origins:
  - https://example.com
  - https://api.example.com
 
# זוהי הערה המסבירה מדוע ה-timeout גבוה
timeout_ms: 30000

לתצורות CI/CD — GitHub Actions, GitLab CI, CircleCI — היכולת של YAML לבטא מבנים מקוננים בצורה נקייה עם הערות שימושית באמת. קובץ workflow של GitHub Actions לעתים קרובות משתרע על פני מאות שורות עם תנאים מקוננים, אסטרטגיות matrix וגושי משתני סביבה. JSON יהיה בלתי קריא. TOML יהיה מסורבל למבנים מקוננים לעומק.

הסכנות הנסתרות ב-YAML

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

בעיית נורווגיה. ב-YAML 1.1 (שזה מה שרוב המנתחים מממשים — לא YAML 1.2), NO בודד מנותח כ-false בוליאני. כך גם no, No, n, N, false, False, FALSE, off, Off ו-OFF. רשימת קודי מדינות ISO 3166-1 כוללת NO עבור נורווגיה. קובץ הגדרות עם רשימת קודי מדינות יהפוך בשקט את נורווגיה ל-false.

# YAML 1.1 — מה שהמנתח באמת רואה
country: NO        # → false (בוליאני)
enabled: yes       # → true (בוליאני)
mode: on           # → true (בוליאני)
debug: off         # → false (בוליאני)

התיקון הוא להוסיף מרכאות לכל מה שאמור להיות מחרוזת: country: "NO". אך כל הפיתוי של YAML הוא שאין צורך להוסיף מרכאות. דרישת מרכאות כדי להימנע מהפתעות מחלישה את יתרון הקריאות של הפורמט.

מספרים אוקטליים. ב-YAML 1.1, מספר המתחיל ב-0 מטופל כאוקטלי. הרשאות קבצים נכתבות לעתים קרובות באוקטל: chmod: 0755. מנתח YAML קורא 0755 כמספר העשרוני 493, לא 755. זה שבר סקריפטים פריסה אמיתיים.

# YAML 1.1 — פרשנות אוקטלית
file_mode: 0755    # → 493 (המקביל העשרוני של האוקטל 0755)

עמימות מחרוזות מרובות שורות. YAML מציע מספר תחבירים למחרוזות מרובות שורות — בלוק מילולי (|), בלוק מקופל (>), ומוטבע. הם מתנהגים בצורה שונה לגבי שורות חדשות, רווחים בסוף וכניסה. בחירה בצורה השגויה מייצרת בשקט את המחרוזת הלא נכונה.

# בלוק מילולי — שומר על שורות חדשות
command: |
  npm install
  npm run build
 
# בלוק מקופל — שורות חדשות הופכות לרווחים (שימושי לטקסט ארוך)
description: >
  This is a long description that will be
  folded into a single line with spaces.

טאבים מול רווחים. YAML לא מאפשר תווי טאב להזחה. עורך שמכניס טאבים בשקט יייצר שגיאת ניתוח — או גרוע מכך, ניתוח שונה בהתאם להגדרת עצירת הטאב.

YAML 1.2 תיקן רבות מהבעיות הללו (כולל רשימת ערכי הבוליאני), אך רוב הכלים עדיין מממשים 1.1. כשמשתמשים ב-YAML, כותבים עבור המנתח שה-toolchain שלך מגיע עמו, שיכול ולא יכול להתאים להנחות שלך.


TOML: מתוכנן להגדרות

TOML (Tom's Obvious Minimal Language) נוצר ב-2013 על ידי Tom Preston-Werner (מייסד-שותף של GitHub) במיוחד כפורמט קובץ הגדרות שבני אדם יכולים לכתוב ומכונות יכולות לנתח ללא עמימות.

מה TOML עושה נכון

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

[database]
host = "localhost"
port = 5432
ssl = true
 
allowed_origins = [
  "https://example.com",
  "https://api.example.com",
]
 
# זוהי הערה המסבירה מדוע ה-timeout גבוה
timeout_ms = 30000

ל-TOML יש תמיכה מובנית לתאריכים ושעות (publishedAt = 2026-04-04), שאותם JSON ו-YAML משאירים כמחרוזות שיישומים מנתחים בעצמם.

כותרות סעיפים ([database], [[servers]]) מפורשות וקריאות. מפתחות עם נקודות (database.host = "localhost") מאפשרים לבטא ערכים מקוננים בשורה. מערך טבלאות ([[servers]]) נותן תחביר נקי לרשימת אובייקטים.

[[servers]]
name = "production"
host = "prod.example.com"
port = 443
 
[[servers]]
name = "staging"
host = "staging.example.com"
port = 443

מפרט TOML מדויק ומגורס. כל מנתח TOML תואם מייצר את אותה תוצאה עבור אותו קלט.

היכן TOML נכשל

TOML עובד טוב לקינון רדוד עד מתון. למבנים מקוננים לעומק — הסוג שמופיע במניפסטים של Kubernetes או ב-playbooks של Ansible — תחביר כותרת הסעיפים הופך לחזרתי. קינון ה-YAML המבוסס על הזחה מתרחב בצורה טבעית יותר לשש או שבע רמות עומק.

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


טבלת השוואה

תכונהJSONYAMLTOMLINI
הערותלאכן (#)כן (#)כן (; או #)
סוגים מפורשיםכןלא (מוסקים)כןלא (הכל מחרוזות)
מחרוזות מרובות שורותלא (escape בלבד)כן (תחבירים מרובים)כן (""")לא
מבנים מקונניםכן (מפורט)כן (תמציתי)כן (מתון)רמה אחת בלבד
סיכון עמימות ניתוחנמוךגבוהנמוך מאודבינוני
כתיבה על ידי אדםבינוניגבוהגבוהגבוה
יצירת מכונהמצויןטובטובגרוע
שימושים נפוציםAPIs, מניפסטיםCI/CD, תזמורתצורת פרויקטתצורת אפליקציה ישנה

מסגרת ההחלטה

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

האם זה בעיקר מיוצר על ידי מכונה או נכתב על ידי אדם?

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

אם אדם כותב ועורך קובץ זה באופן קבוע — הגדרות פרויקט, תיאור סביבה, מניפסט כלי — הערות הן בלתי ניתנות למשא ומתן. זה שולל JSON רגיל.

האם אתה שולט ב-toolchain?

אם אתה כלוא במערכת אקולוגית שמחייבת פורמט — Kubernetes דורש YAML, GitHub Actions דורש YAML, Cargo דורש TOML, package.json הוא JSON — אין החלטה לקבל. השתמש במה שהמערכת האקולוגית מצפה לו.

אם אתה מעצב כלי חדש או קובץ הגדרות חדש מאפס, יש לך בחירה אמיתית.

מה עומק הקינון, ועד כמה הצוות שלך סובלני לבאגים עדינים?

YAML ביטויי אך שביר. צוות שכותב YAML בזהירות, מצטט את כל המחרוזות, מריץ linter, ומבין את ההבחנה בין 1.1 ל-1.2 יכול להשתמש בו בבטחה. צוות שנע מהר, עם הגדרות עורך מגוונות, ואינו מריץ בדיקת YAML ב-CI בסופו של דבר יתקל בבעיית נורווגיה או באג אוקטלי בסביבת ייצור.

TOML הוא הבחירה הבטוחה יותר להגדרות הנכתבות על ידי אדם כשאתה שולט בפורמט. סוגים מפורשים אומרים ששגיאת המנתח מופיעה בזמן ניתוח, לא בזמן ריצה כשנורווגיה הפכה ל-false והיגיון ה-feature flag שלך שבר בשקט.

מדריך מהיר

  • תגובת API או חילופי נתונים בין שירותים: JSON
  • מניפסט חבילה (נכתב בעיקר על ידי מכונה): JSON
  • Kubernetes, Docker Compose, GitHub Actions, Ansible: YAML (לא בחירה)
  • קובץ הגדרות פרויקט חדש שאתה מעצב: TOML
  • פרויקט Rust: TOML (Cargo.toml)
  • פרויקט Python: TOML (pyproject.toml)
  • הגדרות אפליקציה ישנה עם צרכי מפתח-ערך פשוטים: INI (או לעבור ל-TOML)

אימות קבצי ההגדרות שלך

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

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

עבור YAML, yamllint הוא ה-linter הסטנדרטי של CLI. הפעלתו ב-CI אינה אופציונלית אם הצוות שלך כותב YAML בסביבת ייצור. עבור TOML, רוב מערכות אקולוגיות השפות מגיעות עם מאמת מובנה (cargo check מאמת את Cargo.toml ומרומז; python -c "import tomllib; tomllib.load(open('pyproject.toml', 'rb'))" מאמת כל קובץ TOML ישירות).


הפורמט הוא חוזה

כל פורמט שבוחרים הופך לחוזה עם כל מפתח וכלי שנוגע בפרויקט שלך. שינויו מאוחר יותר הוא כואב — לא בלתי אפשרי, אך כואב. ההגירה מ-setup.cfg ו-setup.py אל pyproject.toml במערכת האקולוגית של Python לקחה שנים ועדיין לא הושלמה.

בחר בכוונה. JSON כשמכונות הן הצרכן הראשי ועמידות לניוד קריטית. YAML כשהמערכת האקולוגית מחייבת אותו או כשמבנים מקוננים לעומק צריכים להיות קריאים. TOML כשבני אדם כותבים את הקובץ, הנכונות חשובה, ורוצים שהמנתח יזהה עמימות בזמן הקריאה ולא שתצוף כבאג runtime שישה חודשים מאוחר יותר.

פורמט ההגדרות הוא לא רק פורמט קובץ. זוהי הצהרה על מי עורך את הקובץ, אילו כלים מעבדים אותו, ועד כמה אתה סומך על המרת סוג מרומזת. עשה את ההצהרה הזו במכוון.


צריך לאמת קובץ הגדרות JSON עכשיו? נסה את FileCrank JSON Viewer — הדבק את ה-JSON שלך, תפוס שגיאות מיידית ועצב אותו לקריאות.