Блог ДоверьсяСервису
JSON: как устроен формат и работать с JSON-файлами
JSON, или JavaScript Object Notation, — текстовый формат для представления и обмена структурированными данными. Он используется в API, конфигурациях, импорте, экспорте и сообщениях между системами. Несмотря на происхождение из синтаксиса JavaScript, JSON не привязан к одному языку: его читают стандартные библиотеки большинства платформ.
JSON, или JavaScript Object Notation, — текстовый формат для представления и обмена структурированными данными. Он используется в API, конфигурациях, импорте, экспорте и сообщениях между системами. Несмотря на происхождение из синтаксиса JavaScript, JSON не привязан к одному языку: его читают стандартные библиотеки большинства платформ.
Главное: JSON описывает структуру, но не смысл данных. Файл может быть синтаксически корректным и одновременно содержать неверную валюту, невозможную дату или отсутствующий обязательный идентификатор. Поэтому после parsing обычно нужна проверка контракта и бизнес-правил.
Как выглядит JSON
{
"orderId": 4815,
"status": "new",
"paid": false,
"customer": {
"name": "Анна",
"email": "anna@example.com"
},
"items": [
{"sku": "A-10", "quantity": 2, "price": 349.9},
{"sku": "B-21", "quantity": 1, "price": 1200}
],
"comment": null
}
Внешние фигурные скобки образуют object с парами «имя — значение». Поле customer содержит вложенный object, а items — упорядоченный array из двух objects. Отступы и переносы помогают чтению, но не меняют значение документа.
Какие типы поддерживает JSON
| Тип | Пример | Особенность |
|---|---|---|
| Object | {"id": 7} | Имена свойств — строки |
| Array | ["a", "b"] | Порядок элементов значим |
| String | "текст" | Только двойные кавычки |
| Number | -12.5e2 | Без NaN и Infinity |
| Boolean | true | Литералы в нижнем регистре |
| Null | null | Явное отсутствие значения |
На верхнем уровне допустим любой JSON value, не только object или array. Однако конкретный API может требовать object по собственному контракту. Формат не имеет отдельных типов date, binary, integer и decimal: их представление согласуют стороны обмена.
Правила синтаксиса
- имя свойства заключается в двойные кавычки;
- между именем и значением ставится двоеточие;
- элементы object и array разделяются запятыми;
- после последнего элемента запятая не ставится;
- строки используют двойные, а не одинарные кавычки;
true,falseиnullпишутся строчными буквами;- комментарии стандартным JSON не поддерживаются;
- управляющие символы внутри string экранируются;
- пробел, табуляция и перенос допустимы вне значений string.
Расширения вроде JSON5 допускают дополнительные конструкции, но их нельзя незаметно выдавать за обычный JSON. Получатель со стандартным parser отклонит комментарий, одинарные кавычки или trailing comma.
Object и порядок свойств
JSON object — неупорядоченная коллекция пар name/value. Не следует строить бизнес-логику на позиции свойства в тексте. Если порядок важен, представьте элементы array и явно добавьте поле порядка.
Стандарт синтаксически не запрещает повторяющиеся имена, но поведение библиотек различается: одна оставит последнее значение, другая сообщит ошибку, третья сохранит все пары особым способом. Для переносимости используйте уникальные имена.
Строки и экранирование
Внутри string кавычка записывается как \", обратная косая черта — \\, перенос — \n, табуляция — \t. Unicode-символ можно записать напрямую или escape-последовательностью \uXXXX.
{
"message": "Строка 1\nСтрока 2",
"path": "C:\\data\\report.json",
"quote": "Он сказал: \"готово\""
}
Для обмена между открытыми системами используйте UTF-8. Следите за кодировкой файла и HTTP-заголовками, но не добавляйте случайный BOM: некоторые инструменты обрабатывают его неодинаково.
Числа и точность
JSON описывает десятичную запись number, но не задает одинаковую внутреннюю точность всех реализаций. Среда может преобразовать число в двоичный floating point и потерять точность большого идентификатора. Особенно опасно передавать длинные номера, деньги и точные измерения без контракта.
Идентификаторы, над которыми не выполняют арифметику, безопаснее передавать string. Для денег часто используют integer минимальных единиц либо decimal-строку с явно указанной валютой. Получатель должен валидировать диапазон до вычислений.
JSON и JavaScript object
| JSON | JavaScript object literal |
|---|---|
| Текст для обмена | Синтаксическая конструкция программы |
| Имена только в двойных кавычках | Часть имен может быть без кавычек |
| Нет функций и undefined | Допускаются функции, undefined и другие значения |
| Нет комментариев | Комментарии допустимы в исходном коде |
| Разбирается parser | Интерпретируется как код языка |
Не используйте eval для чтения JSON. В JavaScript предназначен JSON.parse(), который проверяет грамматику и возвращает значение. Для обратной операции применяется JSON.stringify().
Как создать JSON-файл вручную
- Определите контракт: поля, типы, обязательность и единицы измерения.
- Откройте текстовый редактор с подсветкой JSON.
- Создайте object или array и заполните значения.
- Сохраните файл в UTF-8 с расширением
.json. - Запустите синтаксический validator.
- Проверьте schema и бизнес-ограничения.
- Откройте результат тем же parser, которым пользуется получатель.
Категория средств разработки ПО помогает подобрать редактор или IDE. Подсветка и автоформатирование снижают число опечаток, но успешное сохранение файла не доказывает корректность контракта.
Как создать JSON программно
Надежнее собирать структуру средствами языка и сериализовать стандартной библиотекой, а не склеивать строку вручную.
const order = {
orderId: 4815,
status: "new",
paid: false
};
const text = JSON.stringify(order, null, 2);
const restored = JSON.parse(text);
Сериализатор корректно экранирует строки, но не решает все вопросы. В JavaScript свойства со значением undefined могут исчезнуть, а некоторые типы требуют явного преобразования. Всегда тестируйте фактическую структуру на границе системы.
Чем открыть JSON
| Задача | Подходящий инструмент |
|---|---|
| Быстро посмотреть небольшой файл | Текстовый редактор или браузер |
| Редактировать с подсказками | IDE с поддержкой JSON и schema |
| Проверить в терминале | Стандартный parser языка или jq |
| Исследовать HTTP API | API-клиент и инструменты разработчика браузера |
| Работать с большим объемом | Потоковый parser, ETL или аналитическая система |
Не загружайте конфиденциальный документ в случайный онлайн-formatter. Он может содержать токены, персональные данные или внутреннюю структуру системы. Используйте локальный инструмент либо утвержденный корпоративный сервис.
В категории сервисов для разработчиков представлены инструменты разных классов. Перед передачей данных проверяйте политику хранения, регион, доступ команды и возможность маскирования секретов.
Проверка в командной строке
Python умеет разобрать и форматировать файл стандартным модулем:
python3 -m json.tool input.json
При ошибке команда сообщает строку, столбец и позицию. Результат можно записать в новый файл средствами оболочки, не перезаписывая оригинал до успешной проверки. Если установлен jq, команда jq . input.json также валидирует и форматирует документ.
Синтаксический parser отвечает только на вопрос «это JSON?». Проверку «есть ли обязательное поле orderId и является ли оно положительным» выполняет schema или код приложения.
Минификация и pretty print
Pretty print добавляет отступы и переносы для человека. Минификация удаляет незначащие пробелы и уменьшает текст при передаче. Операции должны выполняться parser и serializer: поиск и замена пробелов может повредить string.
Не сравнивайте JSON как обычные строки, если форматирование не является частью требования. Разный порядок свойств и пробелы могут представлять эквивалентные данные. Для подписи или хэширования нужен согласованный механизм canonicalization.
JSON в HTTP API
Для JSON обычно используется media type application/json. Клиент сообщает формат тела через Content-Type, а желаемый формат ответа — через Accept. Само расширение URL не заменяет HTTP-заголовок.
curl -X POST https://api.example.test/orders \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data-binary @order.json
Не повторяйте пример с реальными адресами без проверки авторизации и последствий метода. В production добавьте timeout, обработку кодов ответа, идентификатор запроса и безопасное журналирование без секретов.
JSON Schema
JSON Schema описывает ожидаемые типы, обязательные поля, диапазоны, шаблоны и композицию структур. Схема сама записывается как JSON и указывает dialect через $schema. Получатель должен поддерживать выбранный dialect.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["orderId", "status"],
"properties": {
"orderId": {"type": "integer", "minimum": 1},
"status": {"enum": ["new", "paid", "cancelled"]}
},
"additionalProperties": false
}
Schema не выражает любое бизнес-правило. Ограничение «дата доставки позже оплаты» может потребовать отдельного кода. Также значение default в schema не обязано автоматически заполнять пропущенное поле.
Null, отсутствие и пустое значение
| Состояние | Пример | Возможный смысл |
|---|---|---|
| Поле отсутствует | {} | Не передано или используется прежнее значение |
| Null | {"phone": null} | Значение явно неизвестно или очищено |
| Пустая строка | {"phone": ""} | Передана строка нулевой длины |
| Пустой array | {"phones": []} | Список известен и не содержит элементов |
Формат не назначает этим состояниям бизнес-смысл. Зафиксируйте его в контракте, особенно для PATCH-запросов, импорта и обновления частичных данных.
Даты и бинарные данные
JSON не имеет типа date. Дату обычно передают string в согласованном формате с часовым поясом либо number с документированной единицей времени. Строка без offset может быть неоднозначной, а локальное время — попасть в переход часового пояса.
Binary часто кодируют Base64-строкой, но это увеличивает размер и нагрузку. Для больших файлов лучше отдельная загрузка или бинарный протокол, а JSON оставляют для метаданных и ссылки на объект.
Большие JSON-файлы
Обычный parser часто загружает весь документ в память. Файл в сотни мегабайт может потребовать значительно больше памяти после превращения в объекты. Для больших наборов применяют streaming parser, постраничный API, разбиение на части или формат JSON Lines, если он согласован сторонами.
Категория решений для данных и бизнес-аналитики относится к следующему уровню работы: загрузке, преобразованию и анализу. Не используйте редактор как инструмент обработки набора, который не помещается в память.
Безопасность JSON
- считайте входной JSON недоверенным;
- ограничивайте размер тела, глубину вложенности и число элементов;
- проверяйте типы, диапазоны и обязательные поля;
- не выполняйте строки как код;
- экранируйте данные при выводе в HTML, SQL и shell;
- учитывайте опасные имена свойств и особенности mapping языка;
- не записывайте токены и персональные данные в обычные логи;
- защищайте от zip bomb и чрезмерно сложной schema;
- обновляйте parser и библиотеки validation;
- возвращайте безопасную ошибку без внутреннего stack trace.
Корректный parser предотвращает выполнение текста как программы, но результат все равно может попасть в опасный контекст. Правило безопасности определяется местом использования значения.
Компас синтаксической ошибки
Диагностика за семь шагов
- Сохраните исходный файл отдельно.
- Запустите parser и запишите строку и столбец.
- Проверьте символ непосредственно перед указанной позицией.
- Сопоставьте пары
{}и[]. - Проверьте кавычки, escape и запятые текущего контейнера.
- Сократите проблемный фрагмент до минимального примера.
- После исправления повторите schema и бизнес-проверку.
Parser иногда указывает место, где ошибка стала очевидной, а не где она возникла. Например, незакрытая string обнаруживается на следующей строке. Поэтому сначала смотрите левее и выше позиции, затем уменьшайте пример.
Типичные ошибки
- одинарные кавычки вместо двойных;
- запятая после последнего элемента;
- неэкранированная кавычка или обратная косая черта;
- комментарий внутри обычного JSON;
True,None,undefinedилиNaN;- повторяющиеся имена свойств;
- потеря точности длинного идентификатора;
- неоговоренный формат даты и часовой пояс;
- смешение отсутствия, null и пустой строки;
- доверие к синтаксической проверке без schema;
- открытие секретного файла в случайном онлайн-сервисе;
- загрузка огромного документа целиком в память.
Чек-лист JSON-контракта
- структура и назначение документа описаны;
- имена и типы полей стабильны;
- обязательные и nullable-поля различены;
- даты, деньги и идентификаторы имеют явный формат;
- поведение для неизвестных полей определено;
- пределы размера и вложенности заданы;
- dialect JSON Schema указан;
- примеры проходят parser и schema;
- ошибки возвращают понятную позицию или путь;
- чувствительные значения исключены из логов;
- совместимость изменений проверяется;
- parser получателя протестирован на реальном файле.
Частые вопросы
Можно ли открыть JSON в браузере?
Да, браузер покажет текст, а некоторые автоматически форматируют дерево. Для редактирования и проверки schema удобнее IDE или специализированный локальный инструмент.
JSON — это база данных?
Нет. Это формат представления данных. База обеспечивает хранение, запросы, конкурентный доступ, транзакции и другие свойства, которых сам JSON не определяет.
Допустимы ли комментарии?
В стандартном JSON нет. Если конфигурации нужны комментарии, выберите поддерживаемый формат или храните пояснения отдельно, не рассчитывая на нестандартное расширение parser.
Чем JSON отличается от XML?
У форматов разная модель и экосистема. JSON компактен для объектов и arrays, XML поддерживает элементы, attributes, namespaces и смешанное содержимое. Выбор зависит от контракта и инструментов сторон.
Почему валидный JSON не принимает API?
Синтаксис может быть правильным, но нарушены schema, тип, обязательность, авторизация или бизнес-правило. Проверьте HTTP-код, тело ошибки и документацию endpoint.
Вывод
JSON — небольшой синтаксис для объектов, arrays и примитивных значений, но надежный обмен требует больше, чем правильные скобки. Создавайте структуру сериализатором, используйте UTF-8, валидируйте parser и schema, явно описывайте даты, числа и null, ограничивайте недоверенный ввод и проверяйте файл инструментом получателя. Тогда JSON остается переносимым контрактом, а не источником скрытых несовместимостей.