Работа с payload
Как заменить или частично изменить body ответа перед возвратом клиенту.
|
Эта статья — про изменение response body без разбора его структуры: Application Delivery Controller либо заменяет тело ответа целиком, либо находит в нём текстовые фрагменты по регулярному выражению и заменяет их. Если вам нужно преобразовать body по шаблону (например, разобрать XML и собрать из его полей JSON), используйте плагин |
Что это
Работа с payload — это изменение тела ответа на уровне Application Delivery Controller перед тем, как ответ будет передан клиенту.
Система может полностью заменить response body или найти в нём фрагменты с помощью регулярного выражения и заменить их.
Как работает
-
Клиент отправляет запрос.
-
Наша система получает запрос и сопоставляет его с Route, в котором настроен плагин
response-rewrite. -
Система отправляет запрос на upstream.
-
Upstream возвращает ответ.
-
Система проверяет настройки
response-rewrite.Если настроен атрибут
body, система заменяет тело ответа целиком.Если настроен атрибут
filters, система ищет в исходном body фрагменты с помощью регулярного выражения и заменяет их на новое значение.Если настроен
vars, изменения применяются только к ответам, которые соответствуют заданным условиям, например только к ответам со статусом200. -
Система возвращает клиенту уже изменённый ответ.
Response-rewrite может изменять не только ответ upstream, но и ответ, который сформировала наша система, — например если другой плагин отклонил запрос до обращения к бэкенду.
|
Когда пригодится
Предположим, у вас есть бэкенд, который возвращает технический ответ:
{
"status": "ok",
"internal_code": "ORDER_CREATED",
"message": "created"
}
Клиенту такой ответ не подходит: в нём есть внутренний код, а структура отличается от публичного формата API. При этом менять бэкенд нельзя — этот формат уже используют внутренние сервисы.
Вы добавляете response-rewrite и настраиваете новое тело ответа. Бэкенд продолжает возвращать прежний формат, а клиент получает публичный payload:
{
"result": "success",
"message": "Order created"
}
Атрибуты плагина
| Атрибут | Тип | Обязательный | Значение по умолчанию | Допустимые значения | Что задаёт |
|---|---|---|---|---|---|
|
|
Нет |
— |
От |
Новый HTTP-статус ответа. Если не задан, сохраняется исходный статус. |
|
|
Нет |
— |
— |
Новое тело ответа. При использовании |
|
|
Нет |
|
|
Показывает, что значение |
|
|
Нет |
— |
|
Действия с заголовками ответа. Для работы с payload может пригодиться, если вместе с body нужно изменить, например, |
|
|
Нет |
— |
Строки в формате |
Добавляет заголовки к ответу. Значение можно задать константой или NGINX variable. Если такой заголовок уже есть, новое значение будет добавлено к существующему. |
|
|
Нет |
— |
Константа или NGINX variable |
Устанавливает значения заголовков ответа. Если заголовок уже есть, его значение будет перезаписано. |
|
|
Нет |
— |
Имена заголовков |
Удаляет указанные заголовки из ответа. |
|
|
Нет |
— |
Условия в формате |
Условия, при которых будет выполнено изменение ответа. |
|
|
Нет |
— |
— |
Список правил, которые изменяют response body: находят фрагмент с помощью регулярного выражения и заменяют его на другое значение. Нельзя использовать вместе с |
|
|
Да, если задан |
— |
Регулярное выражение |
Шаблон для поиска фрагмента в response body. |
|
|
Нет |
|
|
Область замены: только первое совпадение или все совпадения в body. |
|
|
Да, если задан |
— |
— |
Значение, на которое нужно заменить найденный фрагмент. |
|
|
Нет |
|
Опции регулярного выражения Lua NGINX module |
Параметры выполнения регулярного выражения. |
Что важно учесть
body и filters нельзя использовать одновременно. Если нужно полностью заменить тело ответа, используйте body. Если нужно изменить только часть исходного body, используйте filters.
Действия с заголовками выполняются в следующем порядке: add, затем remove, затем set.
body_base64 применяется только к значению, которое вы задали в body. Этот атрибут не декодирует тело ответа, полученное от upstream.
Если вы меняете формат body, например возвращаете JSON вместо plain text, настройте соответствующий Content-Type через headers.set.
Если изменения должны применяться не ко всем ответам, используйте vars. Например, можно заменить body только для ответов со статусом 200.
response-rewrite может менять не только ответ upstream, но и ответ, который сформировала наша система. Под ответом, сформированным системой, имеется в виду ответ, который система вернула сама, без обращения к бэкенду. Например, так может произойти, если другой плагин заблокировал запрос или вернул ошибку авторизации.
Как подключить плагин
Через 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": {
"response-rewrite": {
"...": "ваши настройки плагина"
}
},
"upstream": {
"...": "ваши настройки upstream"
}
}'
Здесь id — идентификатор Route, uri — путь, по которому запрос попадает в Route, plugins.response-rewrite содержит конфигурацию плагина, а upstream — настройки бэкенд-серверов.
Пример конфигурации плагина
В этом примере система полностью заменяет body ответа от upstream и возвращает клиенту публичный JSON.
Ответ upstream:
{
"status": "ok",
"internal_code": "ORDER_CREATED",
"message": "created"
}
Настройка плагина response-rewrite:
{
"plugins": {
"response-rewrite": {
"body": "{\"result\":\"success\",\"message\":\"Order created\"}",
"headers": {
"set": {
"Content-Type": "application/json"
}
},
"vars": [
["status", "==", 200]
]
}
}
}
После преобразования клиент получит такой ответ:
{
"result": "success",
"message": "Order created"
}
Здесь body задаёт новое тело ответа, headers.set устанавливает Content-Type: application/json, а vars ограничивает применение правила только ответами со статусом 200.