Перейти к основному содержимому

JSON

Разработчику Аналитику Тестировщику
Архитектору Инженеру


JSON

Основы JSON

JSON (JavaScript Object Notation) — текстовый формат обмена данными. Синтаксис заимствован у литералов объектов JavaScript, но JSON не является исполняемым кодом: это только описание структуры (сериализованные данные).

Формат применяют там, где нужно передать или сохранить структурированные данные в виде, который одинаково понимают разные языки и системы:

  • тело запроса и ответа в REST API и веб-хуках;
  • конфигурация приложений (appsettings.json, package.json, настройки CI);
  • сообщения в очередях и стримах (Kafka, RabbitMQ);
  • документы в NoSQL (MongoDB хранит BSON, близкий к JSON);
  • логи и события (структурированное логирование).

По сравнению с XML JSON обычно короче и быстрее парсится, но не поддерживает комментарии, пространства имён и встроенную схему на уровне стандарта. Для конфигов с комментариями чаще берут YAML; для высокой нагрузки внутри контура — бинарные форматы из статьи MessagePack, BSON, Protobuf. В PostgreSQL тот же логический формат хранят типом JSONB (бинарное дерево, индексы, SQL-фильтры) — это слой БД.

Смежные темы: конфигурационные данные в текстовых форматах, интеграции и API.


Два корневых вида документа

Любой валидный JSON-файл — это ровно одна из двух конструкций:

КореньСинтаксисКогда удобно
Объект{ ... }Настройки, одна сущность, ответ API с полями
Массив[ ... ]Списки однотипных записей, координаты, теги

Объект — набор пар "ключ → значение". Ключи уникальны в пределах одного объекта (повтор ключа в одном объекте — ошибка при разборе в большинстве парсеров).

Массив — упорядоченный список значений. Индексация в коде обычно с нуля ([0], [1], …), хотя в самом JSON индексы не пишут — только элементы через запятую.

Объекты и массивы вкладываются друг в друга без ограничения глубины (на практике лимитируют размером файла и здравым смыслом).


Типы значений

В JSON всего шесть типов данных. Других (дата как отдельный тип, undefined, функции, NaN) в стандарте нет — их кодируют строками или числами по соглашению команды.

ТипВ JSONПримерЗамечание
Строка"...""Москва", "C:\\data"Только двойные кавычки; спецсимволы — через \
Числобез кавычек42, -3.14, 1e6Нет NaN и Infinity
Логическоеtrue / false"active": trueБез кавычек, регистр важен
nullnull"middleName": null"Значение отсутствует", не путать с ""
Массив[ ... ][1, 2, 3]Элементы любых типов, в т.ч. объекты
Объект{ ... }{ "id": 1 }Вложенная структура

Ключ — всегда строка в двойных кавычках: "userId", не userId.

Значение — один из шести типов выше.

Строки и экранирование. Внутри строки обратный слэш \ задаёт спецсимволы:

ПоследовательностьСмысл
\"кавычка в тексте
\\обратный слэш
\nперевод строки
\tтабуляция
\u0041символ по коду Unicode (здесь — A)

Пути Windows в JSON пишут с удвоенным слэшем: "C:\\Users\\Timur\\file.txt".

Числа. Целые и дробные записывают в десятичной форме; экспонента допустима: 1.5e-20.015. Ведущие нули у целых (01) стандартом не поощряются.

null vs отсутствие поля. Если ключа нет в объекте — поле "не передали". Если ключ есть со значением null — поле передали явно как "пустое/неизвестное". Для API и БД это разные смыслы; в контракте их фиксируют отдельно.


Синтаксис и правила

Правила JSON (RFC 8259 / ECMA-404):

  • документ — один объект {...} или один массив [...], не несколько подряд;
  • пары в объекте — "ключ" — значение, элементы разделяются запятой ,;
  • после последнего элемента в объекте или массиве запятой быть не должно (trailing comma — синтаксическая ошибка);
  • ключи и строки — только в двойных кавычках "..."; одинарные '...' недопустимы;
  • ключ без кавычек (name: "Alice") — недопустим (это уже JavaScript, не JSON);
  • комментарии (//, /* */) в JSON запрещены;
  • логические: строго true и false (не True, не 1);
  • массив — [элемент1, элемент2], объект: {"a": 1, "b": 2}.

Минимальные корректные документы:

{}
[]
{"ok": true}

Чит-лист: https://cheatsheets.zip/json
Спецификация: https://www.json.org/json-ru.html


Частые ошибки

Типичные причины, по которым парсер отклоняет "похожий на JSON" текст:

ОшибкаПочему неверно
Запятая после последнего поля{ "a": 1, }
Одинарные кавычки{ 'name': 'Bob' }
Ключ без кавычек{ age: 30 }
Комментарий в файле{ "x": 1 // test }
undefined, функции, NaNне входят в стандарт JSON

Ниже на странице — интерактивный разбор: можно вставить свой текст или выбрать пресет с ошибкой и увидеть сообщение парсера.

Play ITЗагрузка интерактивного демо…


Примеры готовых JSON-документов

Профиль пользователя (объект с вложенностью)

Базовый шаблон — скаляры, массив строк, вложенный объект.

{
"id": 10042,
"name": "Алиса",
"email": "alice@example.com",
"age": 25,
"isStudent": true,
"skills": ["Python", "JavaScript", "SQL"],
"address": {
"city": "Москва",
"zip": "101000",
"country": "RU"
},
"middleName": null
}

Конфигурация приложения

Типичный appsettings / конфиг сервиса:

  • вложенные объекты;
  • числа;
  • строки;
  • флаги.
{
"app": {
"name": "OrderService",
"environment": "production",
"debug": false
},
"server": {
"host": "0.0.0.0",
"port": 8080,
"https": true
},
"database": {
"host": "db.internal",
"port": 5432,
"name": "orders",
"poolSize": 20
},
"features": {
"newCheckout": true,
"legacyImport": false
}
}

Ответ REST API — список заказов

Корень — объект с метаданными и массивом записей (пагинация).

{
"page": 1,
"pageSize": 20,
"total": 2,
"items": [
{
"orderId": "ord-2024-001",
"status": "shipped",
"amount": 4590.5,
"currency": "RUB",
"createdAt": "2024-11-15T10:30:00Z"
},
{
"orderId": "ord-2024-002",
"status": "pending",
"amount": 1200,
"currency": "RUB",
"createdAt": "2024-11-16T08:00:00Z"
}
]
}

Даты в JSON — строки (часто ISO 8601); парсер не знает тип "дата", это соглашение приложения.


Каталог — массив товаров на верхнем уровне

Когда API отдаёт "просто список" без обёртки — корень документа массив.

[
{
"sku": "BOOK-001",
"title": "Вселенная IT",
"price": 990,
"tags": ["учебник", "it"],
"inStock": true
},
{
"sku": "BOOK-002",
"title": "Сети для начинающих",
"price": 750,
"tags": ["сети"],
"inStock": false
}
]

Ошибка API (единый формат ответа)

Удобно для клиентов и тестов — код, сообщение, детали.

{
"success": false,
"error": {
"code": "VALIDATION_FAILED",
"message": "Некорректные поля запроса",
"details": [
{
"field": "email",
"issue": "invalid_format"
},
{
"field": "age",
"issue": "must_be_positive"
}
]
},
"traceId": "8f3c2a1b-4e5d-6c7a-8b9e-0f1a2b3c4d5e"
}

Фрагмент package.json (экосистема Node.js)

JSON как конфиг экосистемы — версии, скрипты, зависимости.

{
"name": "my-app",
"version": "1.2.0",
"private": true,
"scripts": {
"start": "node dist/index.js",
"test": "jest --coverage"
},
"dependencies": {
"express": "^4.21.0"
},
"devDependencies": {
"jest": "^29.7.0",
"typescript": "~5.6.0"
},
"engines": {
"node": ">=20.0.0"
}
}

Геоданные — массив координат

Массив чисел внутри массива объектов — частый приём для полигонов и треков.

{
"route": "delivery-17",
"points": [
{ "lat": 55.7558, "lon": 37.6173, "seq": 1 },
{ "lat": 55.7601, "lon": 37.6200, "seq": 2 },
{ "lat": 55.7620, "lon": 37.6155, "seq": 3 }
],
"distanceKm": 2.4
}

JSON Schema и валидация

Сам JSON не описывает допустимую структуру документа. Для проверки "поле email обязательно, age — число от 0 до 150" используют внешние схемы, чаще всего JSON Schema — отдельный JSON-файл с правилами. В OpenAPI (Swagger) тело запроса/ответа тоже задаётся схемой, совместимой с этим подходом.

Минимальная схема для профиля пользователя:

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["id", "name", "email"],
"properties": {
"id": { "type": "integer", "minimum": 1 },
"name": { "type": "string", "minLength": 1 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 },
"middleName": { "type": ["string", "null"] }
},
"additionalProperties": false
}

На этапе разработки достаточно валидатора в IDE или JSON.parse в коде; в CI схему подключают для контрактных тестов API.


Сериализация и разбор в коде

Парсинг — превращение текста JSON в структуру в памяти. Сериализация — обратная запись в строку или файл. Ошибка синтаксиса ловится на парсинге; "нет такого поля" — уже логика приложения.

JavaScript (браузер и Node.js):

const raw = '{"theme":"dark","port":8080}';
const obj = JSON.parse(raw);
console.log(obj.theme);

const again = JSON.stringify(obj, null, 2);

Python:


import json

raw = '{"theme": "dark", "port": 8080}'
obj = json.loads(raw)
print(obj["theme"])

with open("config.json", "w", encoding="utf-8") as f:
json.dump(obj, f, ensure_ascii=False, indent=2)

Запись и чтение config.json с построчным разбором — Python — работа с файлами и текстом.

C# (.NET):

using System.Text.Json;

var json = """{"theme":"dark","port":8080}""";
var obj = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
var theme = obj!["theme"].GetString();

var bytes = JsonSerializer.SerializeToUtf8Bytes(new { theme = "dark", port = 8080 });

Для типизированных моделей в C# удобнее свой класс с JsonSerializer.Deserialize<AppSettings>(json).


null, отсутствие поля и PATCH

СитуацияСмысл в API
Ключа нет в JSONПоле не передавали (не менять?)
"middleName": nullЯвно "значение пустое / неизвестно"
"middleName": ""Пустая строка — другой смысл, чем null

В контракте OpenAPI это различают через required, nullable и описание метода PATCH.


Сравнение с XML и YAML

КритерийJSONYAMLXML
ЧитаемостьХорошаяОчень высокаяСредняя (многословно)
КомментарииНетДа (#)Да
Типы в стандарте6 базовыхРасширенный набор+ XSD
Типичное применениеAPI, браузер, мобильные клиентыDocker, K8s, AnsibleSOAP, legacy, документы

Выбор формата — что ожидает потребитель: публичный HTTP API почти всегда JSON; человекочитаемый деплой-конфиг — часто YAML.


Практическое задание
  1. Составьте JSON с полями name, age, profession и вложенным объектом contacts (email, phone).
  2. Добавьте массив skills из трёх строк.
  3. Проверьте документ в демо выше или через jsonlint.com.
  4. Намеренно добавьте лишнюю запятую и одинарные кавычки — убедитесь, что парсер сообщает об ошибке.
  5. Сравните тот же смысл в YAML: чем отличается запись вложенности и комментариев?

Основа по протоколу

Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.