Авторский проект IT-специалиста Олега Барабанова Персональные публикации на тему IT и не только…

Основные недостатки JSON

Итак, в настоящее время JSON является очень популярным форматом хранения данных, конфигов, а также удобен как формат передачи текстовых данных. Не в последнюю очередь он стал популярен благодаря стремительному развитию web-технологий и JavaScript в частности.

В данной статье я хотел бы немного обсудить недостатки JSON и затронуть тему JSON5.

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

Пример сравнения, который показывает, насколько немногословен JSON в сравнении с XML:

// Example XML:

<?xml version="1.1" encoding="UTF-8" ?>
<userlist>
  <user name="Иван" surname="Иванов" />
  <user name="Петр" surname="Петров" />
  <user name="Федор" surname="Федоров" />
</userlist>

// Example JSON:

[
  { name: "Иван", surname: "Иванов" },
  { name: "Петр", surname: "Петров" },
  { name: "Федор", surname: "Федоров" }
]

Но тем не менее забегу наперед и скажу, что JSON не является полноценной заменой XML и вытеснил его только там, где не нужна вся мощь стандартов XML.

Естественно у JSON есть не только положительные, но и отрицательные стороны, знание которых поможет вам сориентироваться, где стоит применять JSON, а где нет.

Проблема 1. Отсутствие нормальных комментариев в JSON

На мой взгляд, одним из существенных недостатков этого формата, является отсутствие нормальной поддержки комментариев. Когда данные гоняются в виде JSON при RPC или REST, в этом нет необходимости, но вот когда JSON используется в форматах конфигов - это уже проблема. Когда смотришь в проекте очередной огромный package.json или config.json, то глаза на лоб лезут от отсутствия пояснений по каким-то неочевидным моментам. 

Часто хочется просто оставить маленький комментарий в стиле в стиле того же JS:

...
"rules": {
  "vue/max-attributes-per-line": "off", //disabled because it is not compatible with "Prettier"
}
...

Но в JSON это будет ошибкой. Решением такой проблемы является добавление какого-то свойства, четко обозначающего комментарий:

...
"rules": {
  "__comment__vue/max-attributes-per-line": "disabled because it is not compatible with \"Prettier\"",
  "vue/max-attributes-per-line": "off",
}
...

Т.е. мы фактически добавляем новое значение и должны иметь какое-то соглашение, т.к. по логике мы ожидаем в rules одно правило, а по факту получаем 2. Т.е. там, где обрабатывается JSON, должна стоять последующая фильтрация значений, начинающихся с "__comment__".

Вместо __comment__ можно задать любой признак комментария, какой вам удобен. Даже для такого случая нет какого-то общепринятого наименования таких "комментариев". Да и в общем такие комментарии достаточно уродливы и могут доставить больше проблем чем пользы.

Проблема 2. Хранение бинарных данных в JSON

В силу того, что JSON является текстовым форматом, безопасно хранить в нем в чистом виде бинарные данные не получится. Точно таким же недостатком обладает и XML.

Для решения этой проблемы применяют Base64 кодирование, результат которого можно безопасно использовать в JSON. Но к такому решению надо подходить с осторожностью, т.к. добавление файлов, кодированных base64 имеет следующие последствия:

Стоит рассмотреть возможность вместо непосредственной вставки бинарных данных в JSON, указывать в виде строки ссылку или URI к источнику, с которого можно выгрузить файл.

Проблема 3. Отсутствие BigInteger

О проблеме точности больших чисел (IEEE 754) я уже упоминал в статье "Проблемы больших чисел в JavaScript или зачем нужен тип BigInt".

Вкратце, если в вашем JSON например есть число 23845061135960375, то при парсинге вы скорее всего получите значение 23845061135960376, что может вас достаточно удивить.

Решением этой проблемы является передача больших чисел в виде строки.

JSON5

Попыткой решить часть проблем JSON можно назвать JSON5, который его разработчики называют как "JSON for humans".

По факту, он является интересной идеей (и реализацией!), решения некоторых проблем JSON как формата, причем с полностью сформулированной спецификацией, которая совместима с JSON и просто расширяет его. Т.е. любой JSON является валидным для JSON5, но не любой JSON5 является валидным согласно JSON.

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

Итог

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