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 | Без кавычек, регистр важен |
| null | null | "middleName": null | "Значение отсутствует", не путать с "" |
| Массив | [ ... ] | [1, 2, 3] | Элементы любых типов, в т.ч. объекты |
| Объект | { ... } | { "id": 1 } | Вложенная структура |
★ Ключ — всегда строка в двойных кавычках: "userId", не userId.
★ Значение — один из шести типов выше.
Строки и экранирование. Внутри строки обратный слэш \ задаёт спецсимволы:
| Последовательность | Смысл |
|---|---|
\" | кавычка в тексте |
\\ | обратный слэш |
\n | перевод строки |
\t | табуляция |
\u0041 | символ по коду Unicode (здесь — A) |
Пути Windows в JSON пишут с удвоенным слэшем: "C:\\Users\\Timur\\file.txt".
Числа. Целые и дробные записывают в десятичной форме; экспонента допустима: 1.5e-2 → 0.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
| Критерий | JSON | YAML | XML |
|---|---|---|---|
| Читаемость | Хорошая | Очень высокая | Средняя (многословно) |
| Комментарии | Нет | Да (#) | Да |
| Типы в стандарте | 6 базовых | Расширенный набор | + XSD |
| Типичное применение | API, браузер, мобильные клиенты | Docker, K8s, Ansible | SOAP, legacy, документы |
Выбор формата — что ожидает потребитель: публичный HTTP API почти всегда JSON; человекочитаемый деплой-конфиг — часто YAML.
- Составьте JSON с полями
name,age,professionи вложенным объектомcontacts(email,phone). - Добавьте массив
skillsиз трёх строк. - Проверьте документ в демо выше или через jsonlint.com.
- Намеренно добавьте лишнюю запятую и одинарные кавычки — убедитесь, что парсер сообщает об ошибке.
- Сравните тот же смысл в YAML: чем отличается запись вложенности и комментариев?
Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.