JSON

13 tools

Что такое JSON?

JSON (JavaScript Object Notation) — это лёгкий текстовый формат обмена данными, удобный для чтения и записи людьми и простой в обработке для машин. Изначально производный от JavaScript, JSON не зависит от языка программирования и является де-факто стандартом обмена данными в интернете.

JSON представляет данные в виде пар «ключ-значение», организованных в объекты и массивы. Его простота сделала его доминирующим форматом для REST API, конфигурационных файлов и хранения данных.

Краткая история

JSON был формализован Дугласом Крокфордом в начале 2000-х годов. Спецификация была опубликована на json.org в 2001 году. RFC 4627 вышел в 2006 году, текущий стандарт ECMA-404 — в 2013 году.

До JSON XML был доминирующим форматом обмена данными. Минимализм JSON — без атрибутов, инструкций обработки и пространств имён — сделал его мгновенно популярным. К 2010 году JSON в значительной мере вытеснил XML в веб-API.

Типы данных JSON

JSON поддерживает ровно шесть типов данных. Каждое значение в корректном JSON-документе должно быть одним из них:

String"hello world"

Любая последовательность символов Unicode в двойных кавычках. Поддерживаются escape-последовательности (\n, \t, \").

Number42 / 3.14 / 1e10

Целое число или число с плавающей точкой. Разрешена научная нотация (1e10). Различие между int и float на уровне JSON отсутствует.

Booleantrue / false

Литеральные токены true или false (только строчными буквами). Нет понятия truthy/falsy — только строгий булев тип.

Nullnull

Литеральный токен null (строчными буквами). Представляет отсутствие значения. Отличается от undefined, который не является типом JSON.

Array[1, "two", null]

Упорядоченный список значений в квадратных скобках. Элементы могут быть разных типов, массивы могут быть произвольно вложенными.

Object{"key": "value"}

Неупорядоченная коллекция пар ключ-значение в фигурных скобках. Ключи должны быть строками.

{
  "string":  "hello world",
  "number":  42,
  "float":   3.14,
  "boolean": true,
  "null":    null,
  "array":   [1, 2, 3],
  "object":  { "nested": "value" }
}

Правила синтаксиса JSON

JSON имеет строгие правила синтаксиса. Небольшое отклонение вызывает ошибку разбора. Вот шесть самых важных правил:

Только строки в двойных кавычках

Все строковые значения и ключи объектов должны использовать двойные кавычки. Одинарные кавычки — недопустимый JSON.

Без завершающих запятых

JSON не допускает завершающие запятые после последнего элемента массива или последнего свойства объекта.

Без комментариев

В JSON нет синтаксиса для комментариев. // и /* */ недопустимы. Для конфигурационных файлов с комментариями рассмотрите JSON5 или YAML.

Без undefined и функций

JSON поддерживает только шесть примитивных типов. Значения JavaScript, такие как undefined, NaN, Infinity и функции, не могут быть представлены.

Ключи объектов должны быть строками

Все ключи объектов должны быть строками в кавычках. Числовые ключи или идентификаторы без кавычек недопустимы.

Регистрозависимость

JSON чувствителен к регистру. true, false и null должны быть написаны только строчными буквами.

Недопустимый и допустимый JSON

Недопустимый
{
  'name': 'Alice',       // single quotes — invalid
  age: 30,              // unquoted key — invalid
  "scores": [1, 2, 3,], // trailing comma — invalid
  "note": undefined     // undefined — invalid
}
Допустимый
{
  "name": "Alice",
  "age": 30,
  "scores": [1, 2, 3],
  "note": null
}

JSON в современном вебе

REST API

JSON является стандартным форматом тела для запросов и ответов REST API. Практически каждый язык программирования имеет встроенный парсер JSON.

Конфигурационные файлы

package.json, tsconfig.json, .eslintrc и многие другие инструменты разработчика используют JSON для конфигурации.

NoSQL-базы данных

Документоориентированные базы данных, такие как MongoDB, CouchDB и Amazon DynamoDB, хранят данные в виде JSON-документов.

Состояние и данные фронтенда

localStorage и sessionStorage хранят строки, поэтому JSON.stringify/JSON.parse постоянно используются для сериализации объектов JavaScript.

JSON в сравнении с другими форматами

JSON не всегда лучший выбор. Вот как он сравнивается с другими распространёнными форматами данных:

JSON vs XML
Преимущества JSON над XML

Более простой синтаксис, меньший размер файла, легче разбирать, более читаемый

Недостатки JSON по сравнению с XML

Нет поддержки атрибутов, инструкций обработки или пространств имён XML

Выбирайте XML когда

Нужны метаданные документа, смешанные модели контента или XML-схемы

JSON vs YAML
Преимущества JSON над YAML

Более строгий синтаксис (меньше неоднозначности), лучшая поддержка инструментов, более переносимый

Недостатки JSON по сравнению с YAML

Нет поддержки комментариев, несколько многословнее для глубоко вложенных данных

Выбирайте YAML когда

Конфигурационные файлы, редактируемые людьми, Docker Compose, GitHub Actions, Kubernetes

JSON vs TOML
Преимущества JSON над TOML

Более широкая поддержка экосистемы, более быстрый разбор, более предсказуемая обработка типов

Недостатки JSON по сравнению с TOML

Нет встроенного типа даты, менее удобен для сложных вложенных структур

Выбирайте TOML когда

Rust (Cargo.toml), Python (pyproject.toml), конфигурация приложений в стиле INI

JSON vs CSV
Преимущества JSON над CSV

Структурированные и вложенные данные, не ограниченные плоскими строками и столбцами

Недостатки JSON по сравнению с CSV

Значительно больший размер файла, хуже производительность для чисто табличных данных

Выбирайте CSV когда

Данные электронных таблиц, экспорт баз данных, данные для открытия в Excel или pandas

JSON Schema

JSON Schema — это словарь для проверки структуры JSON-документов. Схема описывает ожидаемые типы, обязательные поля и ограничения JSON-значения.

Такие инструменты, как ajv (JavaScript), jsonschema (Python) и встроенные валидаторы во многих IDE, поддерживают JSON Schema. OpenAPI использует JSON Schema для описания тел запросов и ответов API.

Распространённые проблемы JSON

Потеря точности чисел

Числа JSON разбираются как 64-битные числа с плавающей точкой IEEE 754. Целые числа больше 2^53 теряют точность. Передавайте большие идентификаторы как строки.

Нет типа дата

JSON не имеет типа дата. Даты обычно сериализуются как строки ISO 8601 или Unix-временные метки.

Циклические ссылки приводят к сбою сериализаторов

JSON.stringify генерирует TypeError при наличии циклических ссылок на объекты.

Проблемы с Unicode и BOM

JSON должен быть закодирован как UTF-8, UTF-16 или UTF-32. BOM в начале JSON-файла не соответствует спецификации.

Загрязнение прототипа

При разборе ненадёжного JSON слияние разобранных объектов может быть уязвимо к атакам через ключ __proto__.

Null и отсутствующий ключ

{"key": null} и отсутствующий "key" семантически различны. Null означает, что поле существует с пустым значением; отсутствие означает, что поле не было указано.

Часто задаваемые вопросы

Как расшифровывается JSON?

JSON расшифровывается как JavaScript Object Notation. Несмотря на название, JSON полностью независим от языка программирования.

JSON — это то же самое, что объект JavaScript?

Нет. JSON — это текстовый формат, похожий на объектный литерал JavaScript, но с более строгими правилами: ключи должны быть в двойных кавычках, не поддерживаются undefined, функции и комментарии.

Может ли JSON содержать комментарии?

Нет. Спецификация JSON не включает синтаксис комментариев. Для конфигурационных файлов, требующих комментариев, рассмотрите JSONC, JSON5 или YAML.

В чём разница между JSON и JSONP?

JSONP был обходным путём для политики одного источника браузера. Устарел — используйте CORS.

Как форматировать JSON для удобного чтения?

В JavaScript: JSON.stringify(data, null, 2). В Python: json.dumps(data, indent=2). В терминале: cat file.json | jq .

Что такое NDJSON или JSON Lines?

NDJSON хранит один JSON-объект на строку. Популярен для лог-файлов и крупных экспортов данных.

Важны ли пробелы в JSON?

Пробелы между токенами незначительны. Форматирование — вопрос стиля, а не семантики.

Каков максимальный размер JSON-файла?

Спецификация JSON не устанавливает ограничений по размеру. На практике вы ограничены памятью парсера и пропускной способностью сети.

Может ли JSON представлять бинарные данные?

Не напрямую. Бинарные данные должны быть закодированы в Base64 перед встраиванием в JSON, что увеличивает размер примерно на 33%.

Что такое JSON5?

JSON5 — это надмножество JSON, добавляющее: ключи без кавычек, строки в одинарных кавычках, завершающие запятые, комментарии и многострочные строки.