Всем привет!
Сегодня поговорим об интересном (и таинственном для фронтов) формате YAML. Он считается одним из наиболее популярных форматов для файлов конфигураций.
Файлы с расширением .yaml или .yml вы можете встретить довольно часто, например .travis.yml (для Travis Build), .gitlab-ci.yml (для git lab CI) и др.
И тогда возникают резонные вопросы: что это за формат и чем он отличается от JSON-а?
Цель этой статьи — познакомить вас со структурой YAML, помочь понимать, читать и изменять YAML-файлы. Для тех, кто уже знаком с форматом — напомнить про некоторые его особенности. И сравнить YAML с JSON.
Краткое содержание
Цели создания
Сообщество разработчиков устало от «зоопарка» различных форматов для конфигов, им хотелось упростить себе жизнь и прийти к единому понятному формату. И в 2001 году Кларк Эванс создал YAML 1.0.
Его основные цели:
- быть понятным человеку;
- поддерживать структуры данных, родные для языков программирования;
- быть переносимым между языками программирования;
- использовать цельную модель данных для поддержки обычного инструментария;
- поддерживать потоковую обработку;
- быть выразительным и расширяемым;
- быть лёгким в реализации и использовании.
В официальной документации YAML можно увидеть такое определение:
Рис.1. Определение из официальной документации
Сейчас последняя версия — YAML 1.2, и она в основном используется как формат для файлов конфигурации Ruby on Rails, Dancer, Symfony, GAE framework, Google App Engine и Dart. Также YAML является основным языком описания классов, ресурсов и манифестов для пакетов приложений OpenStack Murano Project и Swagger.io.
YAML vs. JSON
По сути YAML — это расширенная версия известного нам формата JSON.
Чтобы лучше разобраться в формате, давайте сначала рассмотрим пример JSON-конфига:
tsconfig.json
{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": false,
"types": ["node", "lodash", "express"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
Этот файл очень легко читается, мы можем быстро определить, что к чему, но … нужно знать, что у JSON-формата есть некоторые ограничения:
- нельзя создавать переменные;
- нельзя использовать внешние переменные (например, переменные окружения);
- нельзя переопределять значения.
Чтобы смягчить эти ограничения, можно заменить переменные с помощью создания JSON-файлов, а также использовать .eslintrc или .eslint.js. Но в других языках программирования это не вариант, поэтому YAML и стал так популярен.
Попробуем переписать наш пример в формате YAML. Пока рассмотрим только синтаксис, а остальные особенности чуть позже.
*Хабр не умеет подсвечивать YAML, так что пришлось разместить картинки
Как вам? Мне на первый взгляд показалось, что очень похоже на Python, но с какими-то опечатками.
Рассмотрим синтаксис подробнее.
Концепции, типы, синтаксис
Отступы
В YAML для разделения информации очень важны отступы. Нужно помнить, что используются только пробелы, табы не допускаются.
При отсутствии отступа перед первым объявлением YAML поймет, что это корень (уровень 0) вашего файла.
Если вы привыкли использовать tab-ы вместо пробелов, то можно использовать какой-нибудь плагин в вашей IDE, чтобы заменить все пропуски на пробелы (например, editorconfig).
Ключ/Значение
Как и в JSON/JS, в YAML есть синтаксис ключ/значение, и вы можете использовать его различными способами:
Комментарии
Чтобы написать комментарий, вы можете использовать #, а затем ваше сообщение.
Это круто, когда нужно задокументировать какое-то решение или сделать заметку в конфиге. К сожалению, мы не можем так сделать в JSON.
Списки
В YAML есть 2 способа написания списков:
- Синтаксис JSON: массив строк
Помните, что YAML — это расширенный JSON? Поэтому мы можем использовать его синтаксис
people: ['Anne', 'John', 'Max']
- Синтаксис дефиса
Наиболее распространенный и рекомендуемый
people: - Anne - John - Max
Числа
Тут все стандартно: целые числа и числа с плавающей точкой.
Строки
Есть несколько способов объявить строку в YAML:
Если вы хотите использовать какой-нибудь специальный символ, например, _ или @, то нужны будут кавычки.
Напомню, что в JSON у нас есть только один способ написания строк — двойные кавычки.
И главная фишка…
Якорь (переменная или ссылка)
Якорь — это механизм для создания переменных, на которые затем можно ссылаться.
Давайте представим, что вам нужно создать конфигурацию для вашего CI. Он будет иметь версию для production и development сред. Обе версии будут иметь почти одинаковые базовые настройки.
В JSON нам пришлось бы дублировать эти конфиги:
{
"production": {
"node_version": "13.0.0",
"os": "ubuntu",
"package_manager": "yarn",
"run": ["yarn install", "NODE_ENV=${ENVIRONMENT} yarn build"],
"env": {
"ENVIRONMENT": "production"
}
},
"development": {
"node_version": "13.0.0",
"os": "ubuntu",
"package_manager": "yarn",
"run": ["yarn install", "NODE_ENV=${ENVIRONMENT} yarn build"],
"env": {
"ENVIRONMENT": "development"
}
}
}
Копирование и вставка очень раздражают, особенно когда нужно что-то изменить во всех местах.
Якорь решает эту проблему. Для его создания используется символ якоря (&), а для вставки — алиас (*).
Итог
Рис.2. Отсылка к фильму «Матрица»
Возможности YAML-а покоряют при его сравнении с JSON. Но если у вас довольно простой конфиг в пару-тройку строк, то нет смысла усложнять и использовать дополнительные возможности YAML, лучше выбрать JSON. А если же у вас довольно большой и витиеватый файл, то тут однозначно стоит рассмотреть YAML.
У YAML есть еще несколько интересных фишек таких как: многострочный ввод, мерж блоков, матрицы, наследование и другие.
Так как YAML — это расширенный JSON, то мы можем писать YAML-файл в JSON-формате, и он будет работать. Это отличная особенность, которая позволит легче начать изучение YAML.
P.S. Если кто-то хочет напоследок большей жести, то можете почитать про сравнение YAML c XML или про переход с XML на YAML.