Pull to refresh

Comments 60

Ух ты, я работаю с автором этой статьи в одной команде :) Не ожидал увидеть здесь перевод его статьи. Расскажите мне, если не сложно — он достаточно известная личность в iOS разработке?
JSON — это не тот формат данных, на который можно слепо полагаться

Нет в мире совершенства.
Приложение вылетело про открытии статьи
Вот еше интерсная ссылка: http://json5.org
предложения по расширению формата json в соответствии с синтаксисом ECMAScript 5. Цитата из википедии:
Некоторые нововведения:
Поддерживаются как однострочные //, так и многострочные /* */ комментарии.
Объекты и списки могут иметь запятую после последнего элемента (удобно при копипейсте элементов).
Ключи объекта могут быть без кавычек, если они являются валидными идентификаторами ECMAScript 5.
Строки могут заключаться как в одинарные, так и в двойные кавычки.
Числа могут быть в шестнадцатеричном виде, начинаться или заканчиваться десятичной точкой, включать Infinity, -Infinity, NaN и -NaN, начинаться со знака +.

ИМХО вполне разумные предложения, надо бы чтобы их приняли. Сам по себе формат действительно очень красивый, лучше многословного xml и всех форматов основанных на отступах.
Начиная с версии 1.2 YAML считается надмножеством JSON. Т.е. любой валидный JSON документ является валидным YAML документом.
Зоопарк начнется из копипаста, жсон очень ограничен и это дает ему шикарную читаемость даже в больших обьемах. Если начнется цирк из каментариев, запятых в конце и разных кавычек, то в нагрузку еще понадобится форматирование и цветовая схема.
Комментарии нужны для файлов конфигурации и прочих локальных применений. Сейчас это делается отдельными тегами, что плохо.
Запятые в конце — для простой автоматической генерации списков (не нужно думать последний элемент или нет).
Разные кавычки… не знаю, кавычки существуют всего двух типов, может это и имеет смысл а может и нет.
Шестнадцатеричный вид (0x) это общепринятая вещь. Неплохо бы еще двоичный сразу добавить (0b).
Так что но никакого зоопарка, только все самое необходимое для определения данных.
включать Infinity, -Infinity, NaN и -NaN,

профита от этого не понял, если честно
Совместимость с JavaScript, например.
Лично я, хотя и прекрасно понимаю, что JSON это отдельный стандарт, все равно, «в душе» всегда воспринимал JSON как просто объектный литерал JavaScript, из которого, по понятным причинам, убрали тип function. ИМХО, к этому он и должен стремиться.
Вообще, главная проблема JSON в том, что он, с одной стороны, очень похож на JavaScript, а с другой — имеет ряд мелких отличий. Проблемой это является потому, что многие люди обманываются большой схожестью, и не всегда уделяют должное внимание отличиям. К тому же, если отсутствие function вполне понятно, то смысл остальных расхождений с JavaScript не вполне ясен. Как можно уменьшить путаницу? Сделать JSON не похожим на JavaScript просто не получится — это был бы уже совершенно другой формат. А вот привести его в большее соответствие с JavaScript, в принципе можно. Включение Infinity и NaN отлично в эту идею вписывается. И польза тут не столько от самих Infinity и NaN, сколько от большей совместимости с JavaScript.
В то же время, хоть я и назвал вышеописанное «главной проблемой», это не стоит читать как «фатальный недостаток». JSON и в текущем виде вполне неплох. Просто, если что-то и стоит в нем улучшить, то именно совместимость с JavaScript. Так мне кажется. Возможно это от того, что мне часто приходится работать с JSON именно в JavaScript. С другой стороны JSON это ведь «JavaScript Object Notation», а содержимое должно соответствовать названию.
Ограничения JSON вполне разумны. Любой валидный JSON может быть преобразован в JavaScript объект, с этой стороны никаких ограничений нет. Но JSON используется не исключительно JavaScript, я бы даже сказал, в основном для передачи из JavaScript в другую среду и наоборот. А если где-то отсутствует представление Infinity? Еще одно неопределенное поведение? Уж лучше пусть все знают, что это не входит в стандарт, и заранее позаботятся об обработке таких значений.
А по поводу .1, разных кавычек и прочего — это просто грязь и бессмысленное усложнение стандарта. Нормальные сериализаторы такого никогда не выдадут, а у разработчика ручки не отсохнут аккуратно написать.
Пожалуй, только комментарии кажутся полезным дополнением.

Согласен насчёт .1 и кавычек. Но не согласен насчёт inf и NaN — в большинстве систем, где есть числа с плавающей точкой (напомню — таких чисел вообще‐то может и не быть), есть и inf с NaN, иногда даже с двумя NaN. Для получения «неопределённого поведения» по причине «отсутствует представление» совершенно не нужно искать где‐то платформу, на которой есть числа с плавающей точкой, но нет inf и/или NaN — достаточно взглянуть в статью и найти там различные вещи вроде «слишком большое целое», «число с плавающей точкой со слишком большой мантиссой», и т.д. То, что к списку непредставимых чисел с плавающей точкой добавятся ещё два не изменит того, что парсеру хорошо бы как‐то обрабатывать непредставимые числа, и хорошо бы их обрабатывать согласованно (consistently).


Я предпочту лучше иметь возможность сериализовать любое число с плавающей точкой, какое мне может попасться, чем как‐то обрабатывать ситуацию «есть число с плавающей точкой, но в JSON его сериализовать нельзя». Что делать парсеру в проблемных случаях обычно понятнее, чем что делать генератору.

Ничто не мешает обернуть значение в строку и использовать кастомный парсер для сериализации/десериализации.
{ "a": ".1", "b": "NaN", "c": 0.1 }

Может, проще вообще взять и написать свой формат?


  1. Такой вариант точно медленнее, но может быть совершенно медленным. Особенно, если вы делаете что‐то общего назначения и не можете сказать «ключу "b" всегда соответствует float» (т.е. здесь вам придётся как‐то отдельно кодировать NaN, который float и строку "NaN" и проверять все строки), а основная часть парсера написана не вами и на C в целях его ускорения (с этим вы столкнётесь, если, к примеру, попытаетесь расширить стандартный JSON парсер/генератор в Python: самая критичная к производительности часть на C).
  2. Строка, в которой нарушается типизация (а "timeout": inf куда логичнее "timeout": 0.0), в глазах других разработчиков, которые будут её писать, выглядит как‐то костыльно.
  3. Везде, куда вы хотите подсунуть такой JSON, вам нужен свой парсер и свой генератор.
  4. И это совершенно не отменяет того, что в наиболее используемом стандарте представления чисел с плавающей точкой две бесконечности и не‐число есть, почти все конвертеры string→float понимают строки вроде inf или nan (потому как это понимает даже libc’шная strtod — обязана понимать по стандарту, хотя и может понять как «самое большое/маленькое представимое число» (inf) и «что‐то вроде ошибки» (возвращается 0, но во второй аргумент записывается первый, а errno не устанавливается)), а конкурирующие форматы зачастую позволяют записать inf и nan.
Что парсер должен делать с комментариями? Если игнорировать, то комментарии нельзя будет восстановить при обратной сериализации десериализованного объекта. Например, типичный use case, где люди просят комментариев — это файлы конфигурации. Пока эти файлы редактируются в текстовом редакторе человеком — всё прекрасно. Но стоит один раз пропустить конфигурацию через какой-нибудь тул, который парсит структуру, меняет в ней что-то и сохраняет обратно — всё, комментарии пропали.

Если комментарии сохранять при десериализации, то придётся заводить для них новый тип (как в XML) или, скажем, временно запихивать комментарии в «скрытые» поля вроде { "__comment": «This is my comment» }. Но последнее можно делать и самому, если сильно приспичит.
ИМХО, если реализовывать комментарии в полном соответствии с JS, то единственный нормально реализуемый вариант — игнорировать. В частности из-за таких примеров:
{
  my/*Avesome*/Val : "this is awesome value",
  strangeNumber : 10/*000*/00,
}

И если комментарий внутри значения еще можно воспринимать, как что-то вроде:
strangeNumber : [
  10,
  /*000*/,
  00
]

То комментарий в середине ключа приводит нас к тому, что уже и ключ теперь не является простым значением. Он тоже становится массивом из кусков строки и комментариев. По-моему это уж слишком.
Даже если сохранять только комментарии, которые расположены между значениями, возникают дополнительные трудности:
{
  //my first parameter
  "a" : 1,
  //my second parameter
  "c" : 2,
  //my third parameter
  "b" : 3
}

Если в ходе десериализации и последующей новой сериализации параметры будут отсортированы по алфавиту, то комментарии перепутаются и начнут «врать». Хотя, по идее, порядок должен быть не важен, ведь у нас не массив. Но как-то так получается, что все, чего коснулись комментарии становится массивом.
Так что, остается их просто игнорировать. Да, при машинной обработке они потеряются, но это меньшее из зол. Тем более, если конфигурационный файл создается программой, то комментарии должны быть уже в коде этой программы, а не в самом файле конфигурации. Более того, описание параметров конфигурации разумно включать в документацию. Там им будет самое место. Так же описания можно хранить в виде отдельного json, и тогда можно будет генерировать документацию автоматом, и отображать подсказки прямо в визуальном редакторе конфигурации. Все эти методы на порядок лучше, чем писать пояснения в комментариях. Комментарии же уместны и удобны в процессе активной разработки, когда json пишется вручную. Краткие пояснения, TODO, не используемые куски конфига, к которым возможно еще вернешься и т.д. Для всего этого вполне достаточно самой простой реализации, которая просто удалит все комментарии, перед тем, как парсить остальной код.

Интересно было бы посмотреть на результаты ставшего стандартным даже для майкросовтовских библиотек дотнетного Newtonsoft.Json. Он в дотнете благополучно выжил все остальные парсеры из дикой природы.

Посмотрите на гитхабе, там народ в закрытых пул-реквестах уже подобавлял парсеров из разных языков. Однако примерно все они рушатся одинаково :)

Не жуёт не влезающее в double/System.Numerics.BigInteger и жуёт то, что не должен. Ясно, спасибо.

Не хватает в сравнении парсеров в Python. Было бы очень интересно посмотреть, как там обстоят дела.
Интересно, как обстоят дела с реализациями метода JSON.parse() в различных браузерах и вообще парсингом JSON на JS.
Часто использую онлайн-валидаторы JSON. Было бы интересно узнать, как обстоят дела с различными валидаторами JSON, написанными на JS.

Есть ещё один не приянтный момент, связанный с мегапопулярностью JSON: его используют всюду, даже там,
где явно не стоило бы, видимо, надеясь на лёгкую переносимость данных(в любом ЯП есть либа для работы с JSON).


Как пример из личного опыта, могу привести такой случай: человеку надо было перегнать данные из JSON в базу данных, подвох был в том, что json файлы были по 20-40 Gb в одну строку. Помню я очень тогда удивился увидев "однострочный" тридцатигиговый json файл, думаю, что такие объёмы никакая стдлиба ЯП не прожуёт, разве только у тебя не оч. много оперативки на машине где работает разбор подобного файла.


Пришлось писать свой "парсер", который посимвольно/блочно разбивает эту жижу на отдельные json'ы, из которых потом извлекается нужная информация и вставляется в БД.


Мне повезло: это были то ли твиты, то ли месаги с какого-то форума и в них не было "},{".

Вообще нормальные парсеры (тот же JSON.NET) поддерживают потокенный разбор (JsonReader) из байтстрима, а десериализатор, соответственно, можно заставить работать в поточном режиме, вызывая в нужных состояниях парсера. Так что тут проблема не файла, проблема вашего парсера. А так я тоже видел, как люди трёхгигабайтный xml в память полностью грузили для вставки в базу.

ага, тогда смотрел обычный json из стандартной библиотеки python(https://docs.python.org/2/library/json.html)
и что-то я не нашёл тогда ничего альтернативного, потому и пилил свой, видимо, плохо искал,
сейчас вот вижу, на http://stackoverflow.com/questions/10382253/reading-rather-large-json-files-in-python подсказывают, что есть https://github.com/isagalaev/ijson


"a module that will work with JSON as a stream, rather than as a block file."

Кстати говоря, в случае перегонки больших данных из json файлов в БД с целью получения возможности
последующей выборки/анализа онных, можно рассмотреть такой вариант: просто импортнуть в MongoDb.
Этого должно быть достаточно для простенькой выборки, вроде "все коменнты/посты такого-то опльзователя за такой-то период" и т.п.

Ну так результаты разбора не уходят в /dev/null.
В общем случае, когда неизвестно, что делать с разобранными данными, придётся всё дерево держать в памяти.

Потоковые парсеры практически всегда есть, как уже сказали.


Для Ruby, к примеру, Yajl-ruby (насколько помню, основано на потоковом C-парcере Yajl).

А почему бы не использовать XML вместо JSON? Или я чего-то не понимаю…

Слишком «тяжёлый» формат: занимает больше места (и, следовательно, дольше передаётся по сети), дольше разбирается (если, конечно, вы не решите выбрать подмножество XML и написать специальный парсер для него), обычно дольше создаётся (генерация имеет куда бо́льший потенциал оптимизации, чем разбор), сложнее читать человеку, код для работы с разобранной XML обычно длиннее (если только парсер не ваш под ваше подмножество и вы не можете воспользоваться одним из таких парсеров, которые умеют (де)сериализовывать ваши объекты — для Java это вроде обычное дело, а про JavaScript не скажу), много ненужных (в тех случаях, когда выбирают JSON, а не «не нужных» в принципе) возможностей.

Остается только пожелать JSON-у не превратиться в такой же «тяжелый» формат в дальнейшем.

Кстати говоря, BSON, я так понимаю, лишён всех этих подводных камней JSON(если грубо сравнивать), потому что он бинарный: http://bsonspec.org/spec.html


Отсюда мораль: текстовые протоколы передачи данных хорошо, а бинарные ещё лучше(экономичнее, эффективнее, меньше ошибок).

Предвидя, минусующих, скажу: я знаю, что JSON это не протокол передачи данных, а формат, я иммел ввиду в более широком смысле(этот формат в основном и используется для обмена данными между разными компонентами систем, в этом смысле можно провести аналогию с "протоколом передачи данных" работающем поверх http)

Эцсамое, где-то видел сравнение, на котором BSON при всей своей бинарности жрёт больше места чем неотформатированный JSON на выборке "обычных данных".

А в случае использования Newtonsoft.Json он ещё и почему-то медленнее получается.
Недостаток BSON — это жёсткая привязка к конкретным типам данных и ряд ограничений. Преобразование JSON -> BSON не является обратимым.

Вот примеры нелогичных для меня моментов:
1. Длины кусков данных представляются в виде int32. С одной стороны, вылезает ограничение в 2ГБ, с другой — на описание длины коротких списков (а их большинство) все равно приходится тратить по 4 байта. Почему нельзя использовать способ с переменной длиной поля длины, например, так?
2. Почему имя элемента не может содержать символ 0x00?
3. Почему нельзя было boolean false и true сделать просто разными типами? Сэкономили бы целый байт!
4. Зачем тратить байты на символ 0x00 в конце строк?
5. Почему массивы представляются как объекты? Похоже на костыль: ведь для каждого элемента нужно заводить по неспользуемому ключу.
6. Зачем хранить длину массивов и объектов в байтах, когда логичнее хранить количество элементов? Значение меньше — меньше места будет занимать при кодировании с переменной длиной.

Резюме: если разработчики MongoDB решили, что именно такой формат удобен для внутреннего представления данных — да пожалуйста, их право. Только не стоит в этом случае этот формат вытаксивать наружу. На роль компактного формата для передачи данных он не очень годится.

По всему не отвечу ибо не сильно разбираюсь, но по вот этому:


  1. Почему имя элемента не может содержать символ 0x00?
  2. Зачем тратить байты на символ 0x00 в конце строк?

по-моему, очевидно, используется как разделитель/спец символ чтобы в потоке байтов
одно можно было отличить от другого (границы строк "String — The int32 is the number bytes in the (byte*) + 1 (for the trailing '\x00')" )


Резюме: если разработчики MongoDB решили, что именно такой формат удобен для внутреннего представления данных — да пожалуйста, их право. Только не стоит в этом случае этот формат вытаксивать наружу.

Не согласен с Вами, почему не стоит? Стоит хотя бы потому что у них "получилось". Посмотрите на спецификацию — она в сравнении с JSON спецификациями и рфц приведёнными в статье, в разы меньше, лаконичнее и одна. Да, есть какие-то сырые моменты, ну так никто и не говорит, что это идеал.


На роль компактного формата для передачи данных он не очень годится.

Годится: https://en.wikipedia.org/wiki/BSON, раздел Efficiency:


Сompared to JSON, BSON is designed to be efficient both in storage space and scan-speed. Large elements in a BSON document are prefixed with a length field to facilitate scanning. In some cases, BSON will use more space than JSON due to the length prefixes and explicit array indices.


Но да, есть случаи когда выигрыша по сравнению с обычным JSON нет — бсон больше ест (последнее предложение).

С учетом выявленных проблем того и другого в результате был разработан CBOR (https://cbor.io) и стандартизирован в RFC 7049 (а за годы уже и схему подвезли).

по-моему, очевидно, используется как разделитель/спец символ чтобы в потоке байтов
одно можно было отличить от другого (границы строк «String — The int32 is the number bytes in the (byte*) + 1 (for the trailing '\x00')» )

Зачем нужен разделитель, если длина строки передаётся отдельно? А вот невозможность использования строки, содержащей символ 0x00, в качестве ключа, может выйти боком.

Годится: https://en.wikipedia.org/wiki/BSON, раздел Efficiency: ...

Так я предложил идеи, как добиться ещё более компактного представления без изменения функциональности. Впрочем, проще в этом случае уже использовать protobuf — и компактнее, и быстрее.

Так я предложил идеи, как добиться ещё более компактного представления без изменения функциональности. Впрочем, проще в этом случае уже использовать protobuf — и компактнее, и быстрее.

https://github.com/mongodb/mongo/tree/v0.8/db, февраль 2009, уже содержит надпись BSON в разных файлах. https://en.wikipedia.org/wiki/Protocol_Buffers: публичный релиз в июле 2008. Учитывая, что до этой даты никакого релиза не было, писать Mongo начали в октябре 2007 (первое изменение в репозитории), а первое упоминание BSON (в репозитории) было в октябре 2008, в изменении с говорящим комментарием «rename classes» (т.е. BSON в каком‐то виде был и раньше), вы действительно ожидаете использование protobuf в mongoDB? Там уже на момент релиза protobuf было «работает — не трогай».


Кроме того, BSON предоставляет готовую схему с готовым набором типов, а protobuf требует разработки своего набора типов и только так даст вам схему.

Google и разработчики MongoDB придумали собственные форматы для своих нужд, но посчитали ценным выложить их в общий доступ. Я уверен, что разработчики MongoDB при необходимости бы придумали аналог protobuf, но они предпочли BSON в том виде, в котором он сейчас есть.

Они нелогичны только если вы оптимизируете «по длине». «По скорости» наоборот: я не видел исходников MongoDB, но для меня как C разработчика всё выглядит логичным:


  1. При этом чтение длины — один memcpy. В худшем случае ещё и с преобразованием LE→BE (насколько я знаю, одна инструкция в ряде процессоров, за такты не скажу, но точно быстрее ветвлений, неизбежных при использовании переменной длины любого толка).
  2. C’шные строки заканчиваются на 0.
  3. Если вы знаете, что BSON корректный, то просто копируете один следующий байт в bool. Он почти наверняка уже будет в кэше. Хотя, скорее всего, два типа будут всё же быстрее.
  4. Не нужно выделять буфер под строки: если у вас уже есть в памяти буфер с BSON, то когда вам нужно вернуть C’шную строку вы просто возвращаете указатель внутрь этого буфера. Если нулевого байта там не будет, вам придётся либо выделять память, либо отказаться от строковых функций из стандартной библиотеки, даже если вас вполне устраивает, что C’шная строка не переживёт буфера с BSON.
  5. Выглядит как особенность, связанная с реализацией MongoDB.
  6. Логичнее хранить и то, и то: длина в байтах нужна, когда вы хотите найти какой‐то элемент и знаете, что этот — не то, что вам нужно. С длиной в байтах можно быстро сделать seek, сразу увеличить указатель или как‐то ещё пропустить ненужный кусок: при чтении BSON что через read(), что через mmap(), что просто получив char* от какой‐то функции мы можем скакать по байтам, но не по структуре. Без длины в байтах вам придётся прочитать весь массив, чтобы определить, где он заканчивается. Но если же вам нужен именно этот элемент и вы хотите превратить его, скажем, в struct BSONData[], то проще выделить память под возвращаемое значение, имея длину в элементах.

Резюме: если разработчики MongoDB решили, что именно такой формат удобен для внутреннего представления данных — да пожалуйста, их право. Только не стоит в этом случае этот формат вытаксивать наружу. На роль компактного формата для передачи данных он не очень годится.

Бинарные форматы нужны не только потому, что они компактные, но и потому что они быстрые. Разные форматы имеют разный баланс память/скорость, и я не вижу, почему вы считаете, что причины, по которым разработчики BSON частично пожертвовали компактностью, не применимы к другим проектам других разработчиков: кому‐то другому тоже может быть нужен достаточно (для его проекта) компактный формат, который при этом быстр.

4. Не нужно выделять буфер под строки ...

А теперь смотрите нюанс: в отличие от строк-ключей, BSON допускает использование символа 0x00 в строках-значениях. Если этот символ встретится посередине строки, то при работе со строкой как в C-строкой (она же заканчивается на 0!) она будет обрезана.

Бинарные форматы нужны не только потому, что они компактные, но и потому что они быстрые. Разные форматы имеют разный баланс память/скорость, и я не вижу, почему вы считаете, что причины, по которым разработчики BSON частично пожертвовали компактностью, не применимы к другим проектам других разработчиков: кому‐то другому тоже может быть нужен достаточно (для его проекта) компактный формат, который при этом быстр.


Скорость передачи данных по сети существенно меньше скорости парсинга данных (гусары c highload — молчите), поэтому для ориентированного на передачу по сети формата предпочтительнее использовать более компактное представление.

Если же формат разрабатывался для локального использования с упором на скорость, то не вижу ничего плохого в принесении компактности в жертву.
А теперь смотрите нюанс: в отличие от строк-ключей, BSON допускает использование символа 0x00 в строках-значениях. Если этот символ встретится посередине строки, то при работе со строкой как в C-строкой (она же заканчивается на 0!) она будет обрезана.

Смотря какой строкой. Если мы точно знаем, что корректный BSON именно в этой строке не допускает нулевого байта, то эту строку можно использовать и так. Если запрошенный целевой формат в принципе не допускает нулевого байта внутри (а вызывающему может быть глобально пофиг на такое обрезание), то также можно работать и так. Ещё возможно, что написанный код предполагает ветвление — какой‐то более эффективный код в отсутствие нулевого байта внутри и менее в присутствии.


Я замечу, что в проекте Neovim со структурой String поступают также по схожим причинам: хотя String — это и {size_t; char *;}, и иногда может содержать и нулевой байт внутри, char * всё равно оканчивается на нулевой байт просто, потому что так удобнее, а наличие нулевого байта внутри невозможно, допустимо обрабатывать обрезанием или вообще проходит по статье «garbage in — garbage out» (оно же «нам послали строку с нулевым байтом — автор ССЗБ»). Когда нужно ситуация обрабатывается и на наличие/отсутствие нулевого байта в конце всем наплевать (а я лично пишу так, как будто его там нет).

В Web разработке этот формат лучшее, что есть, по крайней мере я не нашёл этому альтернативную замену да и не было для этого причин. Но за статью спасибо!
От XML отошёл полностью.
А теперь ссылки на первоисточник (http://seriot.ch/parsing_json.html) не принято указывать? А то получается, что «Я» по тексту это «Блог компании».


Как вы думаете, куда ведёт ссылка «Nicolas Seriot»?


(Надо, кстати, мне проголосовать.)

UFO just landed and posted this here

Может он и непонятный, но Wayfarer15 тут уже 4 года. Ссылка не бросается в глаза, но чтобы её найти мне достаточно было просто предположить, что перевод оформлен как перевод (полоска около заголовка не особо запоминается).

Первое правило системного/бизнес аналитика в ИТ компании — никогда не assume ("мне достаточно было просто предположить").
Если используешь assume — читай законы Мерфи.

image

А это тут при чём? У вас была гипотеза, что «ссылка на первоисточник не указана». Первым логичным шагом её проверки должно быть предположение, что ссылка‐таки есть, за чем следует поиск ссылки. Т.к. я на хабре тоже не вчера появился, то быстро её нашёл (тем более, что её не прятали от тех, кто в общих чертах понимает логическое разбиение страницы на блоки), но в общем случае можно было применить <C-f> на исходном коде страницы, а не катить бочку на автора, который как раз сделал всё правильно (указал, что статья перевод и где находится оригинал; конкретное место размещения информации уже определялось не им, а дизайнерами TM).

UFO just landed and posted this here
Большинство не используют всех возможностей JSON, описанных в этой статье, а используют некоторое их подмножество, работа с которым вполне безопасна, например для написания package.json, bower.json, babelrc.json, .eslintrc и т.д., для которых есть JSON Schema.
Благодарю за перевод, отличный материал. Добавил пару тасков в свой парсер и утянул тестовый набор. Хотя единственная цель его создания — обеспечить отказоустойчивость rpc сервера, использующего его, я упустил несколько подводных камней. Но теперь возникли серьезные опасения — возможно автор статьи тоже чтото упустил и все еще остались непокрытые сценарии.
RFC-7159 заменен на RFC-8259
Какие отличия не знаю, просто факт.
Sign up to leave a comment.