Потоковая передача JSON
Эта статья может быть слишком технической для понимания большинства читателей . ( декабрь 2015 г. ) |
JSON Потоковая передача включает в себя протоколы связи для разграничения объектов JSON , построенные на основе потоко-ориентированных протоколов нижнего уровня (таких как TCP ), что гарантирует распознавание отдельных объектов JSON, когда сервер и клиенты используют один и тот же объект (например, неявно закодированный). Это необходимо, поскольку JSON — это неконкатенативный протокол (объединение двух объектов JSON не создает действительный объект JSON).
Введение
[ редактировать ]JSON — популярный формат обмена объектными данными между системами. Часто возникает необходимость в отправке потока объектов по одному соединению, например биржевых котировок или записей журнала приложений . [1] В этих случаях необходимо определить, где заканчивается один объект в кодировке JSON и начинается следующий. Технически это называется кадрированием .
Есть четыре распространенных способа добиться этого:
- Отправьте объекты JSON в формате без символов новой строки и используйте новую строку в качестве разделителя. [2]
- Отправьте объекты JSON, объединенные с управляющим символом разделителя записей в качестве разделителя. [3]
- Отправляйте объекты JSON, объединенные без разделителей, и используйте потоковый анализатор для их извлечения.
- Отправляйте объекты JSON с префиксом их длины и используйте потоковый анализатор для их извлечения.
Сравнение
[ редактировать ]JSON с разделителями-строчками очень хорошо работает с традиционными инструментами, ориентированными на строки .
Объединенный JSON работает с красиво напечатанным JSON, но его анализ требует больше усилий и сложности. Он не очень хорошо работает с традиционными линейно-ориентированными инструментами. Объединенная потоковая передача JSON — это расширенная версия потоковой передачи JSON с разделителями строк.
JSON с префиксом длины работает с красиво напечатанным JSON. Он не очень хорошо работает с традиционными построчно-ориентированными инструментами, но может обеспечить преимущества в производительности по сравнению с потоковой передачей с разделителями строк или объединенной потоковой передачей. Это также может быть проще для анализа.
Подходы
[ редактировать ]JSON с разделителями-новой строкой
[ редактировать ]
Два термина для эквивалентных форматов JSON с разделителями строк:
- Разделитель новой строки (NDJSON) [4] [5] — Старое имя было JSON с разделителями строк (LDJSON). [6]
- Строки JSON (JSONL) [7]
Потоковая передача использует тот факт, что формат JSON не допускает символов возврата и новой строки внутри примитивных значений (в строках они должны быть экранированы как \r
и \n
, соответственно) и что большинство форматировщиков JSON по умолчанию не включают пробелы, включая возвраты и символы новой строки. Эти функции позволяют использовать символ новой строки или последовательность символов возврата и новой строки в качестве разделителя.
В этом примере показаны два объекта JSON (неявные символы новой строки в конце каждой строки не показаны):
{"some":"thing\n"}
{"may":{"include":"nested","objects":["and","arrays"]}}
Использование новой строки в качестве разделителя позволяет этому формату очень хорошо работать с традиционными строковыми инструментами Unix .
Например, файл журнала может выглядеть так:
{"ts":"2020-06-18T10:44:12","started":{"pid":45678}}
{"ts":"2020-06-18T10:44:13","logged_in":{"username":"foo"},"connection":{"addr":"1.2.3.4","port":5678}}
{"ts":"2020-06-18T10:44:15","registered":{"username":"bar","email":"[email protected]"},"connection":{"addr":"2.3.4.5","port":6789}}
{"ts":"2020-06-18T10:44:16","logged_out":{"username":"foo"},"connection":{"addr":"1.2.3.4","port":5678}}
который очень легко сортировать по дате, используя grep для имен пользователей, действий, IP-адресов и т. д.
Совместимость
[ редактировать ]JSON с разделителями строк может быть прочитан анализатором, который может обрабатывать объединенный JSON. Объединенный JSON, содержащий символы новой строки внутри объекта JSON, не может быть прочитан анализатором JSON, разделенным строками.
Термины «JSON с разделителями строк» и «JSON с разделителями новой строки» часто используются без уточнения, поддерживаются ли встроенные символы новой строки.
Раньше спецификация NDJ («JSON с разделителями-новой строкой») [8] разрешено встраивание комментариев, если первые два символа данной строки были «//». Это нельзя было использовать со стандартными анализаторами JSON, если были включены комментарии. Текущая версия спецификации («NDJSON — JSON с разделителями-новой строкой). ") [9] больше не содержит комментариев.
Объединенный JSON можно преобразовать в JSON с разделителями строк с помощью подходящей утилиты JSON, такой как jq. Например
jq --compact-output . < concatenated.json > lines.json
JSON с разделителями записей
[ редактировать ]Потоковая передача JSON с разделителем записей позволяет разделять текстовые последовательности JSON без требования, чтобы форматировщик JSON исключал пробелы. Поскольку текстовые последовательности JSON не могут содержать управляющие символы, разделитель записей для разделения последовательностей можно использовать символ- . Кроме того, рекомендуется, чтобы за каждой текстовой последовательностью JSON следовал символ перевода строки , чтобы обеспечить правильную обработку объектов JSON верхнего уровня, которые не являются саморазграничивающими (числа, true, false и null).
Этот формат также известен как текстовые последовательности JSON или тип MIME. application/json-seq
и формально описан в IETF RFC 7464 .
В приведенном ниже примере показаны два объекта JSON, где ␞ представляет управляющий символ разделителя записей, а ␊ представляет символ перевода строки:
␞{"some":"thing\n"}␊
␞{
"may": {
"include": "nested",
"objects": [
"and",
"arrays"
]
}
}␊
Объединенный JSON
[ редактировать ]Объединенная потоковая передача JSON позволяет отправителю просто записывать каждый объект JSON в поток без разделителей. Он полагается на то, что получатель использует синтаксический анализатор , который может распознавать и выдавать каждый объект JSON при анализе завершающего символа. Объединенный JSON — это не новый формат, это просто имя для потоковой передачи нескольких объектов JSON без каких-либо разделителей.
Преимущество этого формата заключается в том, что он может обрабатывать объекты JSON, отформатированные со встроенными символами новой строки, например, красиво напечатанные для удобства чтения человеком. Например, эти два входа действительны и дают один и тот же результат:
{"some":"thing\n"}{"may":{"include":"nested","objects":["and","arrays"]}}
{
"some": "thing\n"
}
{
"may": {
"include": "nested",
"objects": [
"and",
"arrays"
]
}
}
Реализации, которые полагаются на построчный ввод, могут потребовать символ новой строки после каждого объекта JSON, чтобы синтаксический анализатор своевременно создавал объект. (В противном случае строка может остаться во входном буфере, не передав анализатору.) Это редко распознается как проблема, поскольку завершение объектов JSON символом новой строки очень распространено.
JSON с префиксом длины
[ редактировать ]Потоковая передача JSON с префиксом длины или в рамке позволяет отправителю явно указывать длину каждого сообщения. Он полагается на то, что получатель использует анализатор, который может распознавать каждую длину n , а затем читать следующие n байтов для анализа как JSON.
Преимущество этого формата в том, что он может ускорить синтаксический анализ благодаря тому, что точная длина каждого сообщения указывается явно, а не заставляет синтаксический анализатор искать разделители. JSON с префиксом длины также хорошо подходит для TCP-приложений, где одно «сообщение» может быть разделено на произвольные фрагменты, поскольку длина с префиксом сообщает парсеру, сколько именно байтов следует ожидать, прежде чем пытаться проанализировать строку JSON.
В этом примере показаны два объекта JSON с префиксом длины (каждая длина равна длине следующей строки JSON в байтах):
18{"some":"thing\n"}55{"may":{"include":"nested","objects":["and","arrays"]}}
Приложения и инструменты
[ редактировать ]JSON с разделителями-новой строкой
[ редактировать ]- jq может создавать и читать тексты JSON, разделенные строками.
- Джексон (API) может читать и записывать тексты JSON, разделенные строками.
- logstash включает кодек json_lines . [10]
- ldjson-stream модуль для Node.js
- ld-jsonstream модуль без зависимостей для Node.js
- json-stream-es — это библиотека JavaScript/TypeScript (интерфейсная и серверная части), которая может создавать и читать документы JSON, разделенные символом новой строки.
- ArduinoJson — это библиотека C++, поддерживающая JSON с разделителями строк.
- RecordStream Набор инструментов для управления JSON с разделителями строк (генерация, преобразование, сбор статистики и форматирование результатов).
- стандартной библиотеки Go Пакет кодирования/json можно использовать для чтения и записи JSON с разделителями строк.
- RDF4J и Ontotext GraphDB поддерживают NDJSON для JSON-LD (называемый NDJSONLD). [11] с февраля 2021 года. [12]
JSON с разделителями записей
[ редактировать ]- jq может создавать и читать тексты JSON, разделенные разделителями записей.
- json-stream-es — это библиотека JavaScript/TypeScript (интерфейсная и серверная части), которая может создавать и читать документы JSON, разделенные разделителем записей.
Объединенный JSON
[ редактировать ]- concatjson объединенный модуль парсера/сериализатора потоковой передачи JSON для Node.js
- json-stream-es — это библиотека JavaScript/TypeScript (интерфейсная и серверная части), которая может создавать и читать объединенные документы JSON.
- Джексон (API) может читать и записывать объединенный контент JSON.
- jq легкий гибкий процессор JSON командной строки
- Потоковый парсер JSON для Java от Noggit Solr
- Yajl — еще одна библиотека JSON. YAJL — это небольшой анализатор JSON, управляемый событиями (в стиле SAX), написанный на ANSI C, и небольшой проверяющий генератор JSON.
- ArduinoJson — это библиотека C++, поддерживающая объединенный JSON.
- GSON JsonStreamParser.java может читать объединенный JSON.
- json-stream — это потоковый анализатор JSON для Python.
JSON с префиксом длины
[ редактировать ]- Missive Быстрая и легкая библиотека для кодирования и декодирования сообщений JSON с префиксом длины через потоки.
- Собственный обмен сообщениями. Собственный обмен сообщениями WebExtensions.
Ссылки
[ редактировать ]- ^ Райан, Фильм Зерно. «Как мы создавали Filmgrain, часть 2 из 2» . Filmgrainapp.com . Проверено 4 июля 2013 г.
- ^ «Линии JSON» .
- ^ Уильямс, Н. (2015). «РФК 7464» . Запрос комментариев . дои : 10.17487/RFC7464 .
- ^ ndjson на archive.org
- ^ https://github.com/ndjson/ndjson-spec ndjoson-spec на github
- ^ Обновление spec_draft2.md · ndjson/ndjson-spec@c658c26
- ^ Строки JSON
- ^ «JSON с разделителями новой строки» . Джимбо Дж.В. Архивировано из оригинала 22 декабря 2015 г.
- ^ «NDJSON — JSON с разделителями-новой строкой» . Гитхаб . 2 июня 2021 г.
- ^ «Централизованное ведение журнала с помощью Monolog, Logstash и Elasticsearch» .
- ^ «Пакет org.eclipse.rdf4j.rio.ndjsonld» . Фонд Эклипс . Проверено 1 мая 2023 г.
- ^ «Представьте реализацию RDFParser и RDFWriter для формата JSON-LD с разделителями новой строки» . Репозиторий rdf4j на Github . февраль 2021 года . Проверено 1 мая 2023 г.