YAML vs JSON: різниця, приклади і коли що використовувати
YAML vs JSON, якщо коротко: обидва — текстові формати для тих самих типів даних (об’єкти, списки, рядки, числа, булеві значення та null). JSON суворий, використовує фігурні дужки й лапки та є стандартом для веб-API. YAML спирається на відступи, підтримує коментарі, якорі та кілька документів в одному файлі, тож популярний для конфігурацій. YAML 1.2 — майже надмножина JSON.
Спробуйте безкоштовно: Конвертер YAML у JSON Безкоштовно, без реєстрації.
JSON (JavaScript Object Notation, визначений у RFC 8259) створювався для обміну даними між програмами. То що таке YAML? Його назва розшифровується як «YAML Ain’t Markup Language», і його створювали для того, щоб люди читали й редагували дані вручну. У цьому посібнику ті самі дані показано в обох форматах, порівняно їх і розібрано підводні камені кожного. Щоб побачити, як будь-який файл виглядає в іншому форматі, вставте його в безкоштовний конвертер YAML у JSON або конвертер JSON у YAML.
Ті самі дані в JSON і YAML
Ось невелика конфігурація застосунку в JSON:
{
"name": "web-app",
"version": "2.4.1",
"replicas": 3,
"debug": false,
"database": {
"host": "db.example.com",
"port": 5432
},
"features": ["login", "search"],
"maintainer": null
}
А ось ті самі дані в YAML, ще й з коментарем, якого JSON містити не може:
# Settings for the web app
name: web-app
version: 2.4.1
replicas: 3
debug: false
database:
host: db.example.com
port: 5432
features:
- login
- search
maintainer: null
Обидва варіанти розбираються в точно той самий об’єкт. JSON позначає структуру за допомогою {}, [], ком і лапок; YAML — відступами, парами key: value і - для елементів списку. Більшість рядків у YAML узагалі не потребують лапок, тому він читається радше як файл налаштувань, ніж як код.
YAML vs JSON: ключові відмінності
| JSON | YAML | |
|---|---|---|
| Структура | Фігурні й квадратні дужки та коми | Відступи (лише пробіли) |
| Коментарі | Заборонені | # comment |
| Рядки | Завжди в подвійних лапках | Зазвичай без лапок; за потреби 'single' або "double" |
| Типи даних | Об’єкт, масив, рядок, число, булеве значення, null | Ті самі, а також необов’язкові теги, мітки часу в деяких схемах і власні типи |
| Повторне використання | Немає | Якорі &, псевдоніми * і ключі злиття << |
| Кілька документів в одному файлі | Ні (одне значення на файл) | Так, розділені --- |
| Багаторядковий текст | Лише з екрануванням \n |
Блокові скаляри | і > |
| Розбір | Невелика сувора граматика; вбудований у браузери та багато стандартних бібліотек | Більша граматика; зазвичай стороння бібліотека |
| Типове застосування | REST API, package.json, логи, дані, якими обмінюються програми |
Маніфести Kubernetes, воркфлоу GitHub Actions, Docker Compose, Ansible |
Деякі формати приймають обидва: описи OpenAPI можна писати будь-яким із них, а kubectl apply читає маніфести як у JSON, так і в YAML. Загалом JSON виграє, коли дані пишуть і читають програми; YAML — коли люди підтримують їх вручну й потребують коментарів.
Чи є YAML надмножиною JSON?
Майже. Специфікація YAML 1.2 (2009) мала на меті зробити YAML строгою надмножиною JSON, і на практиці парсер YAML 1.2 читає майже будь-який JSON-документ і повертає ті самі дані. Два застереження:
- Дублікати ключів. RFC 8259 лише каже, що ключі об’єкта слід робити унікальними, а YAML цього вимагає, тож строгий парсер YAML відхилить
{"a": 1, "a": 2}. - Парсери YAML 1.1. Багато поширених бібліотек досі дотримуються старіших правил YAML 1.1. PyYAML, наприклад, розпізнає числа з рухомою комою лише тоді, коли вони містять крапку, тож JSON-число
1e3повертається як рядок"1e3".
Навпаки це не працює: більшість YAML не є валідним JSON.
Підводні камені YAML, про які варто знати
«Норвезька проблема» (Norway problem): NO стає false
У YAML 1.1 слова без лапок yes, no, on і off (малими літерами, з великої літери або великими літерами) є булевими значеннями, як і true та false. Тож цей список кодів країн:
countries:
- GB
- NO
- SE
у парсері YAML 1.1, як-от PyYAML, завантажується як ["GB", false, "SE"]. Те саме правило перетворює ключ on: воркфлоу GitHub Actions на булеве True, коли файл завантажують через PyYAML. Базова схема (core schema) YAML 1.2 це виправила: булевими є лише true і false (також у написанні True або TRUE), тож парсер 1.2 залишає NO рядком. Оскільки ви рідко контролюєте, який парсер читатиме ваш файл, безпечна звичка — брати такі значення в лапки: - "NO".
Числа, які не мали бути числами
- Провідні нулі. YAML 1.1 читає
0755як вісімкове число 493. YAML 1.2 читає його як десяткове 755, а вісімкові числа записує як0o755. Поштовий індекс на кшталт01234стає 668 або 1234 залежно від парсера. Беріть його в лапки. - Номери версій.
python-version: 3.10— це число з рухомою комою 3.1, а не «3.10». Пишіть"3.10". - Кінцеві нулі.
1.0— число з рухомою комою, тож під час перетворення на JSON у JavaScript воно стає1.
Табуляції та значущі пробіли
Специфікація YAML забороняє символи табуляції у відступах, тож табуляція на початку рядка — це синтаксична помилка, а не питання стилю. Відступи також несуть зміст: зсув ключа на два пробіли ліворуч переносить його до іншого батьківського об’єкта, і файл може залишатися цілком валідним, але означати вже щось інше.
Багаторядкові рядки: | і >
Літеральний блок (|) зберігає переноси рядків; згорнутий блок (>) з’єднує рядки пробілами:
literal: |
Line one
Line two
folded: >
This long sentence is
folded into one line.
literal стає "Line one\nLine two\n", а folded — "This long sentence is folded into one line.\n". Обидва зберігають один кінцевий символ нового рядка; щоб прибрати його, пишіть |- або >-.
Якорі, псевдоніми та ключі злиття
YAML дає змогу визначити блок один раз і використовувати його повторно:
defaults: &defaults
adapter: postgres
port: 5432
production:
<<: *defaults
host: db.example.com
&defaults дає блоку ім’я, *defaults посилається на нього, а << зливає його ключі, тож production зрештою отримує adapter, port і host. У JSON відповідника немає: під час перетворення на JSON значення копіюються в кожне місце, де вони використовуються. Ключі злиття походять із YAML 1.1 і не входять до базової схеми 1.2, але більшість поширених парсерів досі їх підтримують.
Підводні камені JSON, про які варто знати
JSON суворий, і більшість помилок спричиняють три правила:
- Жодних коментарів.
//і/* */— синтаксичні помилки. - Жодних кінцевих ком.
["a", "b",]— невалідний запис. - Лише подвійні лапки. Ключі мають бути в лапках, а одинарні лапки заборонені.
Тому на цьому файлі JSON.parse видасть помилку:
{
// port for local development
'port': 8080,
"tags": ["api", "v2",],
}
Для файлів, які пишуть вручну, існують м’якші варіанти: JSONC («JSON with comments», тобто JSON із коментарями) використовують налаштування VS Code і tsconfig.json, а JSON5 додатково дозволяє одинарні лапки, ключі без лапок і кінцеві коми. Жоден із них не приймає стандартний парсер JSON. Форматувальник JSON приймає вхідні дані у JSON5, позначає їх як «Дійсний JSON5 — перетворено на строгий JSON» і повертає вам стандартний JSON.
.yaml vs .yml
YAML vs YML — це не питання формату: обидва розширення означають той самий формат, і парсерам байдуже, яке з них ви використовуєте. RFC 9512, який у 2024 році зареєстрував медіатип application/yaml, називає .yaml бажаним розширенням і зазначає, що .yml досі використовується. FAQ проєкту YAML також рекомендував .yaml, а Docker Compose шукає compose.yaml раніше за compose.yml. GitHub Actions приймає обидва варіанти в .github/workflows. Оберіть одне розширення для проєкту й не тримайте config.yaml і config.yml поруч.
Безпека: як безпечно завантажувати недовірений YAML
Повнофункціональні завантажувачі YAML можуть створювати специфічні для мови об’єкти на основі тегів. У Python yaml.load(data, Loader=yaml.UnsafeLoader) може створювати довільні об’єкти Python, а зі спеціально підготовленим файлом — і виконати код. Для файлів, які писали не ви, завжди використовуйте yaml.safe_load(): він створює лише звичайні словники, списки, рядки, числа, булеві значення та null. Починаючи з PyYAML 6.0, yaml.load() відмовляється працювати без явно вказаного Loader. Остерігайтеся також глибоко вкладених псевдонімів (файлів типу «billion laughs»), які розгортаються у величезні структури. У JSON немає ні тегів, ні псевдонімів, тому JSON.parse і json.loads у Python завжди повертають лише прості дані.
Перетворення між YAML і JSON
Обидва конвертери працюють повністю у вашому браузері й використовують відкриту бібліотеку yaml для JavaScript.
Конвертер YAML у JSON розбирає YAML 1.2, розгортає якорі й псевдоніми, застосовує ключі злиття << і перетворює файл із кількома документами --- на JSON-масив. Можна вибрати відступ у 2, 3 (за замовчуванням) або 4 пробіли, табуляцію чи мініфікований вивід, відсортувати ключі за алфавітом і завантажити результат як converted.json. Синтаксичні помилки, як-от табуляцію у відступі, показано з номером рядка й стовпця. Коментарі втрачаються, бо JSON не може їх зберігати.
Конвертер JSON у YAML читає стандартний JSON і JSON5, тож коментарі та кінцеві коми у вхідних даних приймаються, але не переносяться. Він записує YAML із відступом у два пробіли й не має налаштувань. Вивід відповідає YAML 1.2: рядки на кшталт "0755" і "true" беруться в лапки, а NO, yes чи on лишаються без лапок, бо в 1.2 це звичайні рядки. Якщо файл читатиме інструмент YAML 1.1, як-от PyYAML, додайте лапки до цих значень самостійно.
У командному рядку yq від Mike Farah конвертує в обидва боки, а jq перевіряє JSON і гарно його форматує:
yq -o json config.yaml
yq -P -oy config.json
jq . config.json
Коли використовувати YAML, а коли JSON
Вибір JSON vs YAML зазвичай зводиться до того, хто пише файл:
- Використовуйте JSON для даних, якими обмінюються програми: запитів і відповідей API, повідомлень між сервісами, логів, сховища браузера та всього, що генерує код. Він однозначний і підтримується всюди.
- Використовуйте YAML для конфігурації, яку редагують і рецензують люди: маніфестів розгортання, CI-пайплайнів, файлів Compose. Коментарі та легший синтаксис роблять диффи зрозумілішими.
- Дотримуйтеся вимог інструмента. Якщо платформа очікує YAML (GitHub Actions) або JSON (
package.json), використовуйте цей формат, а не конвертуйте.
Якщо обираєте YAML, тримайтеся простоти: відступ у два пробіли, лапки навколо всього, що може прочитатися як булеве значення чи число, і лінтер на кшталт yamllint у CI.
Часті запитання
Чи кращий YAML за JSON?
Загалом жоден не кращий. JSON простіший і суворіший, тому це безпечніший вибір для даних, якими обмінюються програми. YAML людям легше читати й редагувати, і він підтримує коментарі, тому його використовує так багато конфігураційних файлів.
Чи можна використовувати JSON усередині YAML-файлу?
Так. Потоковий стиль (flow style) YAML використовує ті самі дужки, що й JSON, тож ports: [80, 443] або db: {"host": "localhost"} працює всередині YAML-файлу, а парсер YAML 1.2 приймає майже будь-який повний JSON-документ. Головний виняток — дублікати ключів.
Чи можуть у JSON бути коментарі?
Не в стандартному JSON: RFC 8259 не має синтаксису коментарів, і JSON.parse видає помилку на // або /* */. Деякі інструменти приймають JSONC або JSON5, які дозволяють коментарі, але перш ніж передавати файл строгому парсеру, їх треба видалити.
Яка різниця між YAML і YML?
За вмістом — жодної: .yaml і .yml — два розширення файлів для того самого формату. RFC 9512 називає бажаним .yaml, але парсерам YAML розширення байдуже.
Чому YAML перетворює NO чи on на false чи true?
Тому що YAML 1.1 вважає yes, no, on і off булевими значеннями. YAML 1.2 вважає булевими лише true і false, але багато парсерів, зокрема PyYAML, досі використовують правила 1.1. Беріть такі значення в лапки, наприклад country: "NO", і будь-який парсер прочитає їх як рядки.
Спробуйте безкоштовно: Конвертер YAML у JSON Безкоштовно, без реєстрації.