CSHARP_GEPARD Telegram 155
JsonPath в .NET #решение

Представим себе, что есть сервис, который умеет получать данные из Kafka и складывать полученные данные в БД. Без программирования, просто декларативным указанием topic и таблицы в БД. То есть:

1. Сервис работает по запросу (job или unit-of-work).
2. При создании job описывается маппинг данных из Kafka в нужную таблицу.
3. Описывается фильтрация и преобразовывает данных из Kafka так, как пользователю удобно. Ну чтобы не заниматься этим при каждом запросе в БД.

То есть, во-первых, нужен вменяемый API, которым удобно пользоваться. Во-вторых, нужно описание маппинга полей сообщения из Kafka в поля Data-base-object (DBO). Ну и всякая фильтрация (например, отсечение удалённых), выбор определённых полей и некие операции над ними.

Например, нам нужно взять подразделения компании, перенести часть нужных нам полей, а, также, налету, создать поле, в котором лежит полный путь до этого подразделения в дереве (например, "Бизнес-юнит 3/Департамент 2/Подразделение 1"). Представим себе, что в исходном сообщении эти данные есть, но в виде массива родительских подразделений. То есть нужно взять их названия, правильно отсортировать и соединить в строку.

Какой же интерфейс предоставить программистам, чтобы они могли это сделать? Правильно, формализованный JsonPath (RFC). Конечный пользователь тоже не пострадает, так как сможет, с помощью программистов, натыкать такое на UI.

Когда сервис будет вычитывать сообщение из Kafka, исходное сообщение будет преобразовано, размаплено по нужным полям DBO и помещено в базу. Маппинг, при создании job будет выглядеть примерно так.
{
"id": "$.id",
"1c_id": "$.1c.id",
"full_path": "join(sort($.parents, @.lvl), '/')",
"name": "$.name",
"manager_id": "$.manager.oauth.id",
"filters": [
"$.is_deleted == false",
"$.draft == false"
]
}


Но чтобы сделать этот маппинг, увы, нужно приложить усилия. Дело в том, что стандартная (с некоторых пор) библиотека для работы с json в .NET это System.Text.Json. А он не умеет выбирать узел по JsonPath. Опустим и то, что мало кто из библиотек умеет работать с функциями высшего порядка (см. full_path в примере), но это, со скрипом, можно сделать самому.

Основная задача - получение нужных узлов исходного сообщения в Kafka по выражению JsonPath. Для решения этой задачи можно найти несколько библиотек: непотопляемый Newtonsoft.Json, модный Hyperbee.Json, хмурый JsonCons.Net и популярный JsonPath.Net).

Так как сервис представляется весьма нагруженным, а поиск и преобразования по JsonPath - частыми, нужно выбрать именно ту библиотеку, которая работает быстро и, при этом, потребляет мало памяти. Результаты на скриншоте. Кажется, что Newtonsoft.Json или Hyperbee.Json - весьма неплохой выбор, по скорости и потреблению памяти.

Естественно, все эти библиотеки отличаются функционалом и возможностями расширения (например, в данном примере нужно добавлять свои функции к JsonPath для мутации данных). Тот же Newtonsoft.Json огромная и уважаемая библиотека. Однако, если нужно только парсить JsonPath, то выбор похож на очевидный.

Бенчмарк вот тут.

P.S.: Банчмарки включают в себя создание JsonDocument, JsonNode и JObject, чтобы приблизиться к реальной ситуации. В реальности сервис получает одну из этих структур данных и работает с ней. Если эти штуки предварительно создавать, то, в принципе, результат не изменится. Единственное, что изменится - пропадёт аллокация.
P.P.S.: Пакет Microsoft.AspNetCore.JsonPatch исключён из тестирования, так как основывается на Newtonsoft.Json.
P.P.P.S.: Ребята из Hyperbee.Json, кажется, выложили на nuget библиотеку, которая скомпилирована в Debug. Исправили.
👍12👏43🔥1



tgoop.com/csharp_gepard/155
Create:
Last Update:

JsonPath в .NET #решение

Представим себе, что есть сервис, который умеет получать данные из Kafka и складывать полученные данные в БД. Без программирования, просто декларативным указанием topic и таблицы в БД. То есть:

1. Сервис работает по запросу (job или unit-of-work).
2. При создании job описывается маппинг данных из Kafka в нужную таблицу.
3. Описывается фильтрация и преобразовывает данных из Kafka так, как пользователю удобно. Ну чтобы не заниматься этим при каждом запросе в БД.

То есть, во-первых, нужен вменяемый API, которым удобно пользоваться. Во-вторых, нужно описание маппинга полей сообщения из Kafka в поля Data-base-object (DBO). Ну и всякая фильтрация (например, отсечение удалённых), выбор определённых полей и некие операции над ними.

Например, нам нужно взять подразделения компании, перенести часть нужных нам полей, а, также, налету, создать поле, в котором лежит полный путь до этого подразделения в дереве (например, "Бизнес-юнит 3/Департамент 2/Подразделение 1"). Представим себе, что в исходном сообщении эти данные есть, но в виде массива родительских подразделений. То есть нужно взять их названия, правильно отсортировать и соединить в строку.

Какой же интерфейс предоставить программистам, чтобы они могли это сделать? Правильно, формализованный JsonPath (RFC). Конечный пользователь тоже не пострадает, так как сможет, с помощью программистов, натыкать такое на UI.

Когда сервис будет вычитывать сообщение из Kafka, исходное сообщение будет преобразовано, размаплено по нужным полям DBO и помещено в базу. Маппинг, при создании job будет выглядеть примерно так.

{
"id": "$.id",
"1c_id": "$.1c.id",
"full_path": "join(sort($.parents, @.lvl), '/')",
"name": "$.name",
"manager_id": "$.manager.oauth.id",
"filters": [
"$.is_deleted == false",
"$.draft == false"
]
}


Но чтобы сделать этот маппинг, увы, нужно приложить усилия. Дело в том, что стандартная (с некоторых пор) библиотека для работы с json в .NET это System.Text.Json. А он не умеет выбирать узел по JsonPath. Опустим и то, что мало кто из библиотек умеет работать с функциями высшего порядка (см. full_path в примере), но это, со скрипом, можно сделать самому.

Основная задача - получение нужных узлов исходного сообщения в Kafka по выражению JsonPath. Для решения этой задачи можно найти несколько библиотек: непотопляемый Newtonsoft.Json, модный Hyperbee.Json, хмурый JsonCons.Net и популярный JsonPath.Net).

Так как сервис представляется весьма нагруженным, а поиск и преобразования по JsonPath - частыми, нужно выбрать именно ту библиотеку, которая работает быстро и, при этом, потребляет мало памяти. Результаты на скриншоте. Кажется, что Newtonsoft.Json или Hyperbee.Json - весьма неплохой выбор, по скорости и потреблению памяти.

Естественно, все эти библиотеки отличаются функционалом и возможностями расширения (например, в данном примере нужно добавлять свои функции к JsonPath для мутации данных). Тот же Newtonsoft.Json огромная и уважаемая библиотека. Однако, если нужно только парсить JsonPath, то выбор похож на очевидный.

Бенчмарк вот тут.

P.S.: Банчмарки включают в себя создание JsonDocument, JsonNode и JObject, чтобы приблизиться к реальной ситуации. В реальности сервис получает одну из этих структур данных и работает с ней. Если эти штуки предварительно создавать, то, в принципе, результат не изменится. Единственное, что изменится - пропадёт аллокация.
P.P.S.: Пакет Microsoft.AspNetCore.JsonPatch исключён из тестирования, так как основывается на Newtonsoft.Json.
P.P.P.S.: Ребята из Hyperbee.Json, кажется, выложили на nuget библиотеку, которая скомпилирована в Debug. Исправили.

BY C# Heppard




Share with your friend now:
tgoop.com/csharp_gepard/155

View MORE
Open in Telegram


Telegram News

Date: |

The group’s featured image is of a Pepe frog yelling, often referred to as the “REEEEEEE” meme. Pepe the Frog was created back in 2005 by Matt Furie and has since become an internet symbol for meme culture and “degen” culture. Telegram iOS app: In the “Chats” tab, click the new message icon in the right upper corner. Select “New Channel.” You can invite up to 200 people from your contacts to join your channel as the next step. Select the users you want to add and click “Invite.” You can skip this step altogether. Add up to 50 administrators On June 7, Perekopsky met with Brazilian President Jair Bolsonaro, an avid user of the platform. According to the firm's VP, the main subject of the meeting was "freedom of expression."
from us


Telegram C# Heppard
FROM American