YAML
2 інструментів
Формати серіалізації даних
Серіалізація даних — це процес перетворення структурованих даних у формат, придатний для зберігання або передачі з можливістю подальшого відновлення. Різні формати по-різному балансують між зручністю читання людиною, машинним розбором, виразністю та розміром файлу.
JSON, YAML, TOML та XML — чотири домінуючі текстові формати серіалізації у розробці програмного забезпечення. Кожен має переваги, що роблять його найкращим вибором у конкретних контекстах — розуміння цих компромісів дозволяє обирати правильний формат для кожного завдання.
JSON і YAML поруч
JSON і YAML представляють одну й ту саму модель даних. YAML є суворим надмножиною JSON — будь-який коректний JSON-документ є водночас коректним YAML. Нижче наведено однакову конфігурацію, виражену в обох форматах:
{
"server": {
"host": "localhost",
"port": 8080,
"debug": true
},
"database": {
"url": "postgres://localhost/mydb",
"pool": 10
}
}server: host: localhost port: 8080 debug: true database: url: postgres://localhost/mydb pool: 10
YAML використовує відступи замість фігурних дужок і квадратних дужок та опускає лапки у більшості рядкових значень. Це робить його компактнішим і зручнішим для читання у файлах, що редагуються людиною, але вносить чутливість до відступів.
Порівняння форматів
| Формат | Читабельність | Коментарі | Масиви | Найкраще для |
|---|---|---|---|---|
| JSON | ★★★☆☆ | Без коментарів | Нативні | API, обмін даними |
| YAML | ★★★★★ | Так (#) | Нативні | Конфіг-файли, IaC |
| TOML | ★★★★☆ | Так (#) | Нативні | Конфіг застосунку (Rust, Python) |
| XML | ★★☆☆☆ | Так (<!-- -->) | Повторювані елементи | Документи, SOAP, SVG |
Підводні камені YAML
YAML є потужним, але має добре відомі граничні випадки, які несподівано ловлять розробників. Ось найпоширеніші з них:
Значення 'NO' без лапок інтерпретується як булевий false у YAML 1.1. Коди країн NO (Норвегія), OFF, FALSE, N — усі розбираються як false. У YAML 1.2 це виправлено, але багато парсерів досі використовують правила 1.1. Завжди беріть неоднозначні рядки в лапки.
YAML використовує відступи для визначення структури. Один зайвий пробіл або символ табуляції може повністю змінити зміст документа. Табуляція заборонена як відступ у YAML — лише пробіли.
Значення без лапок, що схожі на числа, булеві значення або null, автоматично приводяться до відповідного типу. '1.0' стає числом з плаваючою крапкою, '2024-01-01' — об'єктом дати в деяких парсерах. Беріть в лапки значення, які мають залишатися рядками.
Специфікація YAML явно забороняє символи табуляції для відступів. Редактори, що автоматично замінюють пробіли на табуляцію, непомітно зламають ваш YAML-файл. Налаштуйте редактор на використання пробілів у YAML-файлах.
YAML має два індикатори багаторядкових рядків: | (літеральний блок, зберігає переноси рядків) та > (складений блок, перетворює переноси рядків на пробіли). Плутанина між ними непомітно дає хибний результат.
Якорі (&) та псевдоніми (*) YAML дозволяють повторно використовувати вузли — це потужно, але може створювати циклічні посилання, що призводять до нескінченних циклів або вичерпання пам'яті в наївних парсерах. Перевіряйте YAML з якорями від ненадійних джерел.
Унікальні можливості YAML
Коментарі
YAML підтримує коментарі за допомогою символу #. Це одна з найбільших практичних переваг над JSON для конфіг-файлів — ви можете документувати налаштування прямо в рядку. Коментарі можуть розташовуватися на окремому рядку або після значення.
Якорі та псевдоніми
YAML дозволяє визначити вузол один раз за допомогою &ім'я-якоря та повторно використовувати його будь-де за допомогою *ім'я-якоря. Це усуває повторення у складних конфігураціях. Kubernetes та Docker Compose активно використовують якорі для спільних визначень сервісів.
Багаторядкові рядки
YAML підтримує блокові скалярні значення у двох режимах: літеральний блок (|) зберігає переноси рядків точно так, як написано, — корисно для скриптів і шаблонів. Складений блок (>) об'єднує довгі рядки в один, — корисно для довгих текстових описів.
Коли потрібна конвертація
GitHub Actions, GitLab CI та CircleCI нативно використовують YAML. Під час програмної генерації конфігів пайплайну часто зручніше побудувати JSON-об'єкт і конвертувати його в YAML для фінального виведення.
Ресурси Kubernetes визначаються в YAML, але шаблонізація Helm-чартів і деякі інструменти виводять JSON. Конвертація між форматами дозволяє перевіряти відповіді API та використовувати стандартні JSON-інструменти.
REST API повертають JSON. Коли ці дані потрібно передати в конфіг-системи на основі YAML (Ansible, Salt, Kubernetes), конвертер усуває розрив без ручного переформатування.
Перехід з одного інструменту на інший часто означає конвертацію формату конфігурації. Конвертація між JSON і YAML дозволяє швидко переходити між екосистемами (Node.js → Python, Docker → Kubernetes).
JSON Schema-інструменти зрілішi за YAML Schema. Поширений підхід — авторити конфіг у YAML для зручності читання, конвертувати в JSON для валідації відносно схеми, а потім конвертувати назад для розгортання.
Внутрішні інструменти можуть споживати YAML-конфіги, тоді як зовнішні API вимагають JSON. Конвертер у build-пайплайні синхронізує обидва представлення без підтримки дублюючих файлів.
Часті запитання
Так. YAML 1.2 є суворою надмножиною JSON — будь-який коректний JSON-документ є водночас коректним YAML. Однак YAML 1.1 (досі використовується багатьма парсерами) має кілька граничних випадків, де коректний JSON не є коректним YAML 1.1.
YAML підтримує коментарі, яких немає у JSON. YAML також компактніший для глибоко вкладених структур. Ці дві властивості роблять його бажаним вибором для конфіг-файлів, що редагуються людиною (Docker, Kubernetes, GitHub Actions).
TOML (Tom's Obvious Minimal Language) розроблено для конфіг-файлів. Він має чіткий синтаксис у стилі INI з явними типами та без неоднозначності. Це стандарт для проектів на Rust (Cargo.toml) і Python (pyproject.toml).
Рідко, але потенційно можливо. JSON зберігає порядок ключів у більшості парсерів (хоча специфікація каже, що він невпорядкований). YAML підтримує якорі та теги, яким немає еквівалента в JSON. Для збереження точності при зворотній конвертації дотримуйтесь спільної підмножини.
JSON.stringify перетворює значення undefined на null у масивах і опускає їх з об'єктів. Якщо у JSON-виведенні ви бачите несподівані null або відсутні ключі, то вихідний JavaScript-об'єкт, ймовірно, містив властивості зі значенням undefined.
Так. Оскільки YAML є надмножиною JSON, можна вбудовувати синтаксис JSON безпосередньо всередину YAML-документа. Іноді це робиться для складних вкладених структур, де відступи YAML були б заплутаними.