Парсинг и модификация
Как по шаблону преобразовать тело запроса перед отправкой на upstream и тело ответа перед возвратом клиенту.
|
Эта статья — про изменение body по шаблону: например, разобрать XML и собрать из его полей JSON. Если вам нужно преобразовать response body с помощью регулярных выражений или просто заменить его полностью, используйте плагин |
Что это
Парсинг и модификация контента — обработка тела запроса или ответа на уровне Application Delivery Controller.
Система работает с payload: разбирает исходное body, извлекает из него данные и собирает новое body по заданному шаблону.
Как работает
-
Клиент отправляет запрос.
-
Наша система получает запрос и сопоставляет его с Route, в котором настроен плагин
body-transformer. -
Система определяет, как получить входные данные для шаблона.
Формат body можно указать явно в
input_format, либо система попытается определить его по заголовкуContent-Type. Чтобы использовать query-параметры GET-запроса как входные данные для шаблона, укажитеinput_format: args. Также query-параметры можно получать через переменные контекста, например_ctx.var.arg_name. -
Система подготавливает входные данные в исходном формате.
Для запроса поддерживаются body-форматы
xml,json,encoded,plainиmultipart, а также query-параметры черезargs. Для ответа —xmlиjson. -
Подготовленные данные становятся доступны в шаблоне, который вы настроили.
Поля из разобранного JSON, XML, encoded-body или query-параметров можно использовать напрямую. Для multipart-запросов данные формы доступны через
context, напримерcontext.age, а multipart-body можно изменять через объектcontext._multipart. Также в шаблоне доступны исходное тело через_body, переменные контекста через_ctx, функции_escape_json()и_escape_xml(). -
Система применяет шаблон и собирает новое body.
Если преобразуется запрос, новое body отправляется на upstream. Если преобразуется ответ, новое body возвращается клиенту.
Когда пригодится
Предположим, у вас есть новый публичный REST API, но внутри всё ещё работает старый SOAP-сервис. Клиенты отправляют JSON с понятной структурой, а бэкенд ждёт XML/SOAP.
Чтобы связать эти части системы, вы добавляете плагин body-transformer и настраиваете преобразование JSON в XML перед отправкой запроса на upstream. Если нужно, можно настроить и обратное преобразование: из XML-ответа бэкенда в JSON-ответ для клиента.
В результате клиент работает с обычным JSON API, а старый сервис получает запросы в нужном ему формате.
| Если upstream ожидает не только другой формат body, но и другой Content-Type, заголовок нужно настроить отдельно. |
Атрибуты плагина
| Атрибут | Тип | Обязательный | Значение по умолчанию | Допустимые значения | Что задаёт |
|---|---|---|---|---|---|
|
|
Нет |
— |
— |
Настройки преобразования тела запроса. |
|
|
Нет |
Определяется по |
|
Исходный формат данных для шаблона: body запроса или query-параметры GET-запроса при значении |
|
|
Да, если задан |
— |
— |
Шаблон для нового тела запроса. |
|
|
Нет |
|
|
Показывает, что шаблон запроса передан в формате |
|
|
Нет |
— |
— |
Настройки преобразования тела ответа. |
|
|
Нет |
Определяется по |
|
Исходный формат тела ответа. |
|
|
Да, если задан |
— |
— |
Шаблон для нового тела ответа. |
|
|
Нет |
|
|
Показывает, что шаблон ответа передан в формате |
Что важно учесть
Если input_format не задан, Application Delivery Controller пытается определить формат body по Content-Type. Для query-параметров GET-запроса формат нужно указать явно: input_format: args — этот режим использует query-параметры как входные данные для шаблона, но не меняет HTTP-метод запроса. Если формат не распознан, шаблон применяется напрямую.
Шаблоны используют синтаксис lua-resty-template. Значение template должно быть валидной JSON-строкой. Сам результат преобразования не обязан быть JSON: шаблон может сформировать JSON, XML, HTML, YAML или другой текстовый формат.
Если шаблон содержит кавычки, переносы строк или большой XML-фрагмент, его нужно корректно экранировать или передать в base64 и включить template_is_base64.
Для plain тело запроса не разбирается на поля. Исходная строка доступна в шаблоне через _body.
Как подключить плагин
Через API
Плагин можно добавить к Route через Admin API. Для этого отправьте запрос на создание или обновление Route:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${admin_key}" \
-d '{
"id": "route-id",
"uri": "/example",
"plugins": {
"body-transformer": {
"...": "ваши настройки плагина"
}
},
"upstream": {
"...": "ваши настройки upstream"
}
}'
Здесь id — идентификатор Route, uri — путь, по которому запрос попадает в Route, plugins.body-transformer содержит конфигурацию плагина, а upstream — настройки бэкенд-серверов.
Пример конфигурации плагина
В этом примере система принимает JSON, меняет структуру body и отправляет в upstream уже преобразованное тело.
Исходный запрос:
{
"product_id": "SKU-1001",
"quantity": 2,
"source_channel": "mobile"
}
Настройка плагина body-transformer :
{
"plugins": {
"body-transformer": {
"request": {
"input_format": "json",
"template": "{\"item\":\"{{product_id}}\",\"count\":{{quantity}},\"channel\":\"{{source_channel}}\",\"source\":\"api-gateway\"}"
}
}
}
}
После преобразования upstream получит такое тело запроса:
{
"item": "SKU-1001",
"count": 2,
"channel": "mobile",
"source": "api-gateway"
}
Здесь input_format: json говорит системе разобрать входной body как JSON. В template задана новая структура тела: product_id превращается в item, quantity — в count, source_channel — в channel, а поле source добавляется на уровне нашей системы.