Кратко
- Формат сериализации определяет, как состояние объекта превращается в последовательность байт. Один и тот же объект можно записать десятком разных способов.
- JSON: синтаксис пришел из литералов объектов JavaScript, шесть типов данных, читается человеком, стандарт де-факто для веб-API.
- YAML: структура задается отступами, поэтому он компактнее JSON. Умеет якоря и алиасы, чтобы не повторять одно и то же, и знает больше типов структур данных.
- XML: дерево тегов, самый многословный из читаемых форматов, но по распространенности не уступает JSON и YAML.
- BSON: двоичный JSON. Человеку не читается, зато умеет даты и бинарные вложения. На нем работает MongoDB.
- Protocol Buffers: двоичный формат со схемой в отдельном файле. Имена полей не передаются вовсе, поэтому он компактнее всех остальных, но без схемы данные не прочитать.
- Position based protocol: только значения через разделитель, без имен полей. Занимает в разы меньше места, но без описания структуры данные не разобрать.
Для начала вспомним, что же такое сериализация.
Сериализация это процесс сохранения состояния объекта в последовательность байт.
Десериализация это процесс восстановления объекта из этих байт.
Java-объект можно сериализовать и передать по сети (например, на другой компьютер).
Так вот, эта самая последовательность байт может быть представлена в разных форматах. Тебе это знакомо из повседневного использования компьютера.
К примеру, электронная книга (или простой текстовый документ), которую ты читаешь, может быть записана в куче разных форматов:
- docx (формат Microsoft Word);
- pdf (формат Adobe);
- mobi (обычно используется в устройствах Amazon Kindle);
- и еще много всего (ePub, djvu, fb2...).
| Формат | Читается человеком | Объем | Чем интересен | Где чаще встречается |
|---|---|---|---|---|
| JSON | Да | Средний | Шесть типов данных, библиотеки под любой язык | Веб-API, обмен фронтенда с бэкендом |
| YAML | Да | Компактнее JSON: структура на отступах | Якоря и алиасы, набор структур !!map, !!omap, !!pairs, !!set, !!seq |
Файлы конфигурации |
| XML | Да | Самый многословный | Дерево тегов с вложенными элементами | Корпоративные системы, конфигурации |
| BSON | Нет, двоичный | Компактнее JSON | Даты, бинарные вложения, куски JavaScript-кода | MongoDB |
| Protocol Buffers | Нет, двоичный | Самый компактный из текстовых и двоичных: имена полей не передаются | Схема в отдельном файле, генерация классов, встроенное версионирование | Общение сервисов между собой, gRPC |
| Position based protocol | Да, но без имен полей | Минимальный | Только значения через разделитель | Там, где важен объем передаваемых данных |
JSON
JavaScript Object Notation. С ним ты уже немного знаком! Мы говорили о нем вот в этой лекции, а сериализацию в JSON рассматривали вот тут. Свое название он получил не просто так. Объекты Java, преобразованные в JSON, действительно выглядят точно так же, как объекты в языке JavaScript. Тебе вовсе не нужно знать JavaScript, чтобы понять смысл нашего объекта:
{
"title": "Война и мир",
"author": "Лев Толстой",
"year": 1869
}
Не обязательно передавать один объект. JSON может содержать и массив объектов:
[
{
"title": "Война и мир",
"author": "Лев Толстой",
"year": 1869
},
{
"title": "Бесы",
"author": "Федор Достоевский",
"year": 1872
},
{
"title": "Чайка",
"author": "Антон Чехов",
"year": 1896
}
]
Синтаксис JSON вырос из литералов объектов JavaScript, оттуда же у него и набор типов данных:
- строки (string);
- числа (number);
- объекты (object);
- массивы (array);
- boolean-значения (true и false);
- null.
Преимущества JSON
Какие же преимущества есть у JSON?Human-readable («человеко-читаемый») формат. Это очевидное преимущество, если твой конечный пользователь это человек. К примеру, на твоем сервере хранится база данных с расписанием авиаперелетов. Клиент-человек запрашивает данные из этой базы с помощью веб-приложения, сидя дома за компьютером. Поскольку тебе нужно предоставить данные в формате, который он сможет понять, JSON будет отличным решением.
Простота. Можно сказать, элементарность :) Выше мы привели пример двух JSON-файлов. И даже если ты вообще не слышал о существовании JavaScript (и уж тем более о его объектах), ты легко поймешь, что за объекты там описаны.
Вся документация JSON это одна веб-страница с парой картинок.Широкая распространенность. JavaScript это доминирующий язык фронтенда, и он диктует свои условия. Использование JSON это необходимость. Поэтому огромное число веб-сервисов используют JSON в качестве формата для обмена данными. Каждая современная IDE поддерживает JSON-формат (в том числе Intellij IDEA). Для работы с JSON написана куча библиотек для всех возможных языков программирования.
Недостатки JSON
Раз обещали и недостатки, вот они.- Нет комментариев. В формате их просто не предусмотрено, так что пояснить что-то прямо в файле не выйдет. Для конфигураций это ощутимо.
- Скудный набор типов. Даты нет, ее передают строкой или числом и договариваются о формате отдельно. Двоичных данных тоже нет: картинку придется закодировать в Base64 и смириться с тем, что она подрастет примерно на треть.
- Объем. Имена полей повторяются в каждом объекте массива, а числа и даты записаны текстом. На тех же данных двоичные форматы заметно компактнее.
- Структура сама себя не описывает. Проверить, что пришел ожидаемый набор полей нужного типа, можно только отдельным инструментом вроде JSON Schema.
YAML
В начале своего существования расшифровывался как Yet Another Markup Language, то есть «еще один язык разметки». В то время его позиционировали как конкурента XML. Сейчас же, по прошествии времени, он расшифровывается как «YAML Ain’t Markup Language» («YAML не язык разметки»). Что же он из себя представляет? Давай представим, что нам нужно создать 3 класса персонажей для нашей компьютерной игры: Воин, Маг и Вор. У них будут следующие характеристики: сила, ловкость, выносливость, набор оружия. Вот как будет выглядеть наш YAML-файл с описанием классов:
classes:
class-1:
title: Warrior
power: 8
agility: 4
stamina: 7
weapons:
- sword
- spear
class-2:
title: Mage
power: 5
agility: 7
stamina: 5
weapons:
- magic staff
class-3:
title: Thief
power: 6
agility: 6
stamina: 5
weapons:
- dagger
- poison
YAML-файл имеет древовидную структуру: одни элементы вложены в другие. Вложенностью мы можем управлять при помощи некоторого количества пробелов, которым обозначаем каждый уровень.
Преимущества YAML
Какими же преимуществами обладает YAML-формат?Human-readable. Опять же, даже увидев yaml-файл без описания, ты легко поймешь, какие объекты там описаны. YAML насколько хорошо читается человеком, что главная страница yaml.org это обычный yaml-файл :)
Компактность. Структура файла формируется за счет пробелов: нет необходимости использовать скобки или кавычки.
Поддержка структур данных, «родных» для языков программирования. Огромное преимущество YAML перед JSON и многими другими форматами заключается в том, что он поддерживает разные структуры данных. В их числе:
!!map
Неупорядоченный набор пар ключ:значение без возможности дубликатов;!!omap
Упорядоченная последовательность пар ключ:значение без возможности дубликатов;!!pairs
Упорядоченная последовательность пар ключ:значение с возможностью дубликатов;- !!set
Неупорядоченная последовательность значений, которые не равны друг другу; - !!seq
Последовательность произвольных значений;
Некоторые из этих структур знакомы тебе по Java! :) За счет этой фичи в формат YAML можно сериализовать разные структуры данных из языков программирования.
Возможность использования anchor и alias
Переводятся слова «anchor» и «alias» как «якорь» и «псевдоним». В принципе, он довольно точно описывает суть этих терминов в YAML.
Они позволяют тебе идентифицировать какой-то элемент в yaml-файле, и ссылаться на него в остальных частях этого файла, если он встречается повторно. Anchor создается с помощью символа
&, а alias с помощью*.Допустим, у нас есть файл с описанием книг Льва Толстого. Чтобы не писать имя автора каждый раз вручную, мы просто создадим якорь «leo» и будем ссылаться на него с помощью алиаса, когда нам это будет нужно:
books: book-1: title: War and Peace author: &leo Leo Tolstoy year: 1869 book-2: title: Anna Karenina author: *leo year: 1873 book-3: title: Family Happiness author: *leo year: 1859Когда мы будем считывать этот файл каким-то парсером, на месте нашего алиаса в нужных местах будет подставляться значение «Leo Tolstoy».
- В YAML можно встроить данные в других форматах. Например, JSON:
books: [ { "title": "War and Peace", "author": "Leo Tolstoy", "year": 1869 }, { "title": "Anna Karenina", "author": "Leo Tolstoy", "year": 1873 }, { "title": "Family Happiness", "author": "Leo Tolstoy", "year": 1859 } ]
Недостатки YAML
Обратная сторона у YAML тоже есть, и растет она из тех же самых свойств.- Структура держится на пробелах. Лишний или потерянный пробел меняет вложенность, и файл либо не читается вовсе, либо читается не так, как задумано. Табуляцию для отступов спецификация прямо запрещает: «tab characters must not be used in indentation, since different systems treat tabs differently».
- Простота обманчива. Документация JSON помещается на одну страницу, а спецификация YAML это несколько десятков страниц с якорями, тегами типов, несколькими документами в одном файле и прочим. Язык целиком мало кто знает.
- Парсеры ведут себя по-разному. Из-за размера спецификации библиотеки поддерживают ее не полностью, и один и тот же файл в разных инструментах может разобраться неодинаково.
- Глубокую вложенность тяжело читать глазами: на пятом уровне отступов уже не видно, к чему относится ключ.
Другие форматы сериализации
XML
Этот формат основан на так называемом дереве тегов.
<book>
<title>Harry Potter and the Philosopher’s Stone</title>
<author>J. K. Rowling</author>
<year>1997</year>
</book>
Каждый элемент состоит из открывающего и закрывающего тега (<> и </>). У каждого элемента могут быть вложенные элементы.
XML это распространенный формат, не уступающий JSON и YAML (если говорить об использовании в реальных проектах). Об XML у нас есть отдельная лекция.
BSON (binary JSON)
Как и следует из его названия, очень похож на JSON, но не является human-readable и оперирует данными в двоичном формате. За счет этого он очень удобен при хранении и передаче изображений и других вложений. Кроме того, BSON поддерживает некоторые типы данных, недоступные в JSON. Например, в BSON-файл можно записать дату (в формате миллисекунд) или даже кусок JavaScript кода. Популярная NoSQL база данных MongoDB хранит информацию именно в BSON формате.Protocol Buffers
Формат от Google и самый распространенный двоичный формат обмена в индустрии. Устроен он иначе, чем все предыдущие: сначала структуру сообщения описывают в отдельном файле схемы с расширением.proto,
message Book {
string title = 1;
string author = 2;
int32 year = 3;
}
а потом по этой схеме генерируют классы для нужного языка, в том числе для Java.
Что это дает. В поток попадают только номера полей и значения, имена полей туда не пишутся вообще, поэтому сообщение получается в разы компактнее JSON. Разбор быстрее: парсеру не нужно ничего угадывать, структура известна заранее. И версионирование встроено в сам формат: старый код спокойно прочитает сообщение с новыми полями и просто пропустит то, чего не знает.
Плата очевидна: без схемы данные не прочитать ни человеку, ни программе. Поэтому Protocol Buffers берут там, где обе стороны свои, а объем и скорость важнее удобства чтения: во внутреннем общении сервисов, в gRPC, в мобильных приложениях.
Position based protocol
В некоторых ситуациях нам необходимо резко снизить количество передаваемых данных (например, если данных очень много и нужно уменьшить нагрузку). В этой ситуации мы можем использовать position based protocol, то есть передавать значения параметров без названий самих параметров.
"Leo Tolstoy" | "Anna Karenina" | 1873
Данные в таком формате занимают в разы меньше места, чем полноценный JSON файл.
Конечно, существуют и другие форматы сериализации, но тебе сейчас не нужно знать их все :) Хорошо, если ты будешь знаком с теми форматами, которые сейчас являются промышленным стандартом при разработке приложений, и будешь помнить их преимущества и отличия друг от друга.
А наша лекция на этом подошла к концу :)
Не забудь решить пару задач сегодня!
До новых встреч! :)
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
в геттона улицах в случае воров)