Все статьи
Руководства

Сериализация данных: JSON, XML, Protocol Buffers

Что такое сериализация, форматы, сравнение, производительность, использование в API.

15 апреля 2025
9 мин чтения
ConvertHub
#сериализация#json#api

Введение

Каждый раз, когда данные передаются между процессами, сохраняются на диск или уходят по сети, они проходят через сериализацию — преобразование из внутренних структур программы в линейную последовательность байтов. Без сериализации невозможен ни один API, ни одна база данных, ни один кэш. JSON, XML, Protocol Buffers, MessagePack, Avro — это всё форматы сериализации, каждый со своими компромиссами между читаемостью, размером, скоростью и типизированностью. В этой статье разберём, что такое сериализация, какие бывают форматы, в чём их отличия и как выбрать подходящий для конкретной задачи.

Что такое сериализация

Сериализация (serialization) — это процесс перевода структуры данных из оперативного представления (объекты в памяти, деревья, графы) в линейный формат, пригодный для хранения или передачи. Обратный процесс называется десериализацией (deserialization, или unmarshalling): из линейного формата восстанавливается исходная структура. Сериализация — фундамент распределённых систем: без неё микросервисы не смогли бы общаться, базы данных — хранить сложные объекты, а веб-страницы — получать данные от сервера.

Хороший формат сериализации должен удовлетворять нескольким требованиям: быть компактным (экономить трафик и место), быстрым для кодирования и декодирования, поддерживать типы данных (числа, строки, булевы, массивы, объекты), быть переносимым между языками программирования и платформами, поддерживать эволюцию схемы (добавление и удаление полей без нарушения совместимости). Идеального формата не существует — каждый компромисс в одном месте отнимает в другом.

Классификация форматов

Форматы сериализации делятся на две большие группы: текстовые и бинарные. Текстовые (JSON, XML, YAML, TOML) читаемы человеком, легко отлаживаются, но занимают больше места и медленнее парсятся. Бинарные (Protocol Buffers, MessagePack, Avro, CBOR, BSON) компактны и быстры, но не читаются без специальных инструментов. Внутри каждой группы есть деление на самописные (self-describing — JSON, XML) и требующие внешней схемы (Protocol Buffers, Avro).

ФорматТипСхемаЧитаемостьРазмерСкорость
JSONТекстовыйСамоописывающийВысокаяСреднийСредняя
XMLТекстовыйСамоописывающийСредняяБольшойНизкая
YAMLТекстовыйСамоописывающийОчень высокаяМаленькийНизкая
Protocol BuffersБинарныйВнешняя (.proto)НетМаленькийВысокая
MessagePackБинарныйСамоописывающийНетМаленькийВысокая
AvroБинарныйВнешняя (JSON-схема)НетОчень маленькийВысокая

JSON: король веба

JSON (JavaScript Object Notation) — самый популярный формат сериализации в вебе. Он появился в 2001 году как упрощённая альтернатива XML, и к 2010-м фактически вытеснил XML из REST API. JSON поддерживает шесть типов данных: строка, число, булево, null, массив, объект. Этого достаточно для 95% задач, и именно эта простота сделала JSON универсальным стандартом.

Главные плюсы JSON: читаемость (текстовый формат), нативная поддержка в JavaScript (через JSON.parse и JSON.stringify), универсальность (есть парсеры во всех языках), компактность по сравнению с XML. Минусы: нет типов (числа без различения int/float, нет даты), нет комментариев (стандарт запрещает, хотя есть JSONC/JSON5), большой размер для числовых данных (числа кодируются как текст), медленный парсинг для больших объёмов.

// Пример JSON
{
  "user": {
    "id": 42,
    "name": "Анна Иванова",
    "email": "anna@example.com",
    "roles": ["admin", "editor"],
    "active": true,
    "createdAt": "2025-04-09T10:30:00Z"
  }
}

// JavaScript: нативная сериализация
const data = { user: { id: 42, name: "Анна" } };
const json = JSON.stringify(data, null, 2);  // beautify
const parsed = JSON.parse(json);              // десериализация

Для сложных задач поверх JSON строятся расширения: JSON Schema (описание и валидация структуры), JSON-LD (связанные данные), JSON API (стандарт для API), JSON5 (с комментариями и relaxed-синтаксисом), JSONC (с comments от Microsoft). Если вам нужно работать с JSON, используйте наш JSON форматтер или конвертеры JSON в XML иJSON в YAML.

XML: классика enterprise

XML (eXtensible Markup Language) — текстовый формат с тегами, похожий на HTML, но с произвольной структурой. Появился в 1996 году, был стандартом для SOAP-сервисов, конфигов, документооборота. Сегодня XML используется реже, но всё ещё встречается в enterprise-системах: банковские системы, бухгалтерия (1С), офисные документы (DOCX, XLSX — это ZIP с XML внутри), SVG, RSS, Sitemap.xml.

Плюсы XML: расширяемость (можно создавать любые теги и атрибуты), мощная экосистема (XPath, XSLT, XSD-схемы, пространства имён), поддержка типов через XSD, возможность валидации. Минусы: избыточность (закрывающие теги, атрибуты), большой размер, медленный парсинг, сложность для чтения больших документов. XML оправдан в enterprise и документообороте, но для новых проектов обычно выбирают JSON.

<!-- Тот же объект в XML -->
<user>
  <id>42</id>
  <name>Анна Иванова</name>
  <email>anna@example.com</email>
  <roles>
    <role>admin</role>
    <role>editor</role>
  </roles>
  <active>true</active>
  <createdAt>2025-04-09T10:30:00Z</createdAt>
</user>

<!-- Тот же объект в JSON занял бы на 30–40% меньше места -->

Protocol Buffers: бинарная эффективность

Protocol Buffers (protobuf) — бинарный формат от Google, разработанный в 2001 году для внутренних нужд и открытый в 2008. Использует внешнее описание схемы в .proto-файлах, из которых генерируется код для разных языков. Protobuf в 3–10 раз компактнее JSON и в 10–100 раз быстрее парсится. Используется в gRPC, внутренних API Google, многих микросервисных архитектурах.

// Схема в .proto-файле
syntax = "proto3";

message User {
  int32 id = 1;
  string name = 2;
  string email = 3;
  repeated string roles = 4;
  bool active = 5;
  int64 createdAt = 6;  // timestamp вместо строки
}

// Сериализация (Python)
import user_pb2
user = user_pb2.User(id=42, name="Анна", email="anna@example.com")
data = user.SerializeToString()  # ~30 байт вместо ~150 в JSON

# Десериализация
parsed = user_pb2.User()
parsed.ParseFromString(data)

Плюсы protobuf: компактность, скорость, строгая типизация, поддержка эволюции схемы (через optional/repeated поля и номера), богатая ecosystem (gRPC, Buf, документация схем). Минусы: не читается без схемы, нужен кодогенератор для каждого языка, сложнее дебажить (нужны инструменты), бинарный формат не подходит для прямого просмотра в браузере.

MessagePack и Avro: альтернативы

MessagePack — бинарный формат, по структуре повторяющий JSON, но в бинарной форме. Самоописывающий, не требует внешней схемы. По размеру в 2–3 раза компактнее JSON, парсится быстрее. Удобен, когда нужно уменьшить payload без усложнения инфраструктуры. Используется в Redis, Memcached, некоторых realtime-протоколах.

Avro — бинарный формат из Apache Hadoop экосистемы. Использует JSON-схему для описания данных, но сам сериализованный формат не содержит имён полей (только значения) — поэтому ещё компактнее protobuf. Схема передаётся вместе с данными или согласуется заранее. Avro оптимален для потоковой обработки больших объёмов данных: Kafka, Hadoop, хранилища данных.

Сравнение производительности

Сравним размеры и скорости для типичного объекта (User с 6 полями, как в примерах выше). Цифры приблизительные, зависят от реализации и данных, но порядок величин показателен.

ФорматРазмер (байты)Сериализация (мкс)Десериализация (мкс)
JSON1521235
XML23845120
YAML118180450
MessagePack6248
Protocol Buffers3423
Avro2835

Разница колоссальная: protobuf в 4,5 раза компактнее JSON и в 10 раз быстрее. Для высоконагруженных систем с миллионами запросов в секунду это критично. Однако для типичного CRUD-приложения с тысячами запросов разница незаметна — JSON справляется легко, и его читаемость перевешивает преимущество в скорости.

Когда что выбирать

JSON

  • Публичные REST API — читаемость важнее компактности.
  • Конфиги и документы для людей — package.json, tsconfig.json.
  • Browser-server communication — нативная поддержка в JS.
  • Бэкенды с малой и средней нагрузкой — до 10k RPS.
  • Прототипирование и разработка — легко дебажить.

XML

  • Интеграция с legacy-системами — SOAP, банковские сервисы.
  • Документооборот — счета, акты в 1С.
  • Сложные документы с проверкой — XSD-схемы, валидация.
  • SVG, RSS, Sitemap — форматы, где XML стандартизирован.

Protocol Buffers

  • Внутренние API микросервисов — gRPC.
  • Высоконагруженные системы — десятки тысяч RPS.
  • Стриминг данных между сервисами — компактность и скорость.
  • Межъязыковое взаимодействие — кодогенерация для всех языков.

Avro

  • Хранение больших объёмов — Parquet, ORC под капотом.
  • Стриминг в Kafka — schema registry, эволюция схем.
  • Big Data пайплайны — Hadoop, Spark, Flink.

Эволюция схемы

Реальные системы меняются: добавляются поля, удаляются, переименовываются. Формат должен поддерживать эволюцию без нарушения совместимости. JSON справляется легко — неизвестные поля просто игнорируются при десериализации, отсутствующие становятся undefined. XML — через optional-атрибуты и пространства имён. Protobuf — через номера полей (можно удалять, нельзя переиспользовать номера), reserved fields, optional-поля. Avro — через схему с правилами совместимости (backward, forward, full).

Для публичных API с внешними клиентами эволюция критична. JSON + JSON Schema с optional-полями и версионированием — простой и эффективный подход. Для внутренних API с жёсткой типизацией protobuf с правилами эволюции — лучший выбор.

Безопасность при десериализации

Десериализация — известная категория уязвимостей. Если десериализовать недоверенные данные без проверки, можно получить удалённое выполнение кода (RCE). Классический пример — Java-сериализация с полиморфными объектами: атакующий подсунул сериализованный объект с вредоносным кодом, который выполнился при десериализации. Аналогичные уязвимости были в Python pickle, Ruby Marshal, PHP unserialize.

JSON и XML относительно безопасны — парсеры не выполняют код. Но есть нюансы: XXE (XML External Entity) — атака через XML-сущности, позволяющая читать файлы сервера. JSON Hijacking — атака на старые браузеры через JSONP. В современных парсерах XXE отключён по умолчанию, но проверяйте конфигурацию. Для protobuf и Avro безопасность выше — данные жёстко типизированы схемой.

Заключение

Сериализация — невидимая, но критическая часть любой системы. JSON — оптимальный выбор для большинства веб-API благодаря читаемости, простоте и универсальности. XML оправдан в enterprise и документообороте. Protocol Buffers и Avro — для высоконагруженных систем и big data, где важна компактность и скорость. Выбор формата — это компромисс между читаемостью, размером, скоростью и типизацией. Для новых проектов начинайте с JSON, и переходите на бинарные форматы только когда упрётесь в производительность. Подробнее о JSON — в нашей статье «JSON форматтер: зачем нужен и как использовать», о сравнении JSON и XML — в материале «JSON vs XML».

Попробуйте эти инструменты

Похожие статьи