Контентная маршрутизация
Как изменить URI, с которым запрос уйдёт на upstream, чтобы публичный API и внутренний бэкенд могли использовать разные пути.
Что это
Контентная маршрутизация в данном сценарии — это изменение пути запроса на уровне Application Delivery Controller перед передачей запроса на upstream.
Как работает
-
Клиент отправляет запрос.
-
Наша система получает запрос и сопоставляет его с Route, в котором настроен плагин
proxy-rewrite. -
Система формирует URI, с которым запрос будет отправлен на upstream.
Новый upstream URI можно задать явно через
uriили собрать по регулярному выражению черезregex_uri. Если используетсяregex_uri, система сопоставляет исходный путь URI с регулярным выражением и подставляет найденные части в новый upstream URI path через переменные$1,$2,$3и т.д. Дополнительно плагин может изменить HTTP-метод,Hostили заголовки запроса. -
Система отправляет на upstream запрос с новым URI.
Если в плагине дополнительно настроены
method,hostилиheaders, запрос уходит на upstream также с изменённым HTTP-методом,Hostили заголовками запроса.
Когда пригодится
Предположим, у вас есть публичный API с путём /api/v1/products/SKU-1001, а внутренний бэкенд ожидает запросы по пути /internal/items/SKU-1001.
Менять бэкенд неудобно: этот путь уже используется другими внутренними сервисами. Менять публичный API тоже нельзя: на него уже завязаны клиенты.
Чтобы связать эти части системы, вы добавляете плагин proxy-rewrite и настраиваете преобразование URI перед отправкой запроса на upstream. В результате клиент продолжает обращаться к /api/v1/products/SKU-1001, а upstream получает запрос к /internal/items/SKU-1001.
Атрибуты плагина
| Атрибут | Тип | Обязательный | Значение по умолчанию | Допустимые значения | Что задаёт |
|---|---|---|---|---|---|
|
|
Нет |
— |
Поддерживает NGINX variables, например |
Upstream URI, с которым запрос будет отправлен на upstream. Можно задать новый путь и при необходимости добавить query-параметры. |
|
|
Нет |
— |
|
HTTP-метод, с которым запрос будет отправлен на upstream. |
|
|
Нет |
— |
— |
Правила для преобразования upstream URI по регулярному выражению на основе исходного URI клиента. В массиве указывается одна или несколько пар, каждая из которых состоит из регулярного выражения и нового URI. Найденные части можно использовать через |
|
|
Нет |
— |
— |
Значение заголовка |
|
|
Нет |
— |
|
Действия с заголовками запроса. Можно добавить, удалить или перезаписать заголовки перед отправкой запроса на upstream. Если передать объект заголовков без |
|
|
Нет |
— |
Константа, NGINX variables или значения из |
Добавляет значения к заголовкам запроса. Если заголовок уже есть, новое значение добавляется к существующему: итоговое значение выглядит как |
|
|
Нет |
— |
Константа, NGINX variables или значения из |
Устанавливает значения заголовков запроса. Если заголовок уже есть, его значение будет перезаписано. Не используйте |
|
|
Нет |
— |
Имена заголовков |
Удаляет указанные заголовки из запроса перед отправкой на upstream. |
|
|
Нет |
|
|
Позволяет использовать исходный URI запроса без нормализации. Значение |
Что важно учесть
Если одновременно настроены uri и regex_uri, приоритет будет у uri. В этом случае правила из regex_uri не будут определять итоговый URI.
Если нужно изменить Host, используйте атрибут host, а не headers.set.
Если в headers указано несколько действий, они выполняются в таком порядке: add, затем remove, затем set.
Как подключить плагин
Через 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": {
"proxy-rewrite": {
"...": "ваши настройки плагина"
}
},
"upstream": {
"...": "ваши настройки upstream"
}
}'
Здесь id — идентификатор Route, uri — путь, по которому запрос попадает в Route, plugins.proxy-rewrite содержит конфигурацию плагина, а upstream — настройки бэкенд-серверов.
Пример конфигурации плагина
В этом примере система принимает запрос к публичному URI, извлекает из него идентификатор товара и отправляет запрос на другой URI внутреннего бэкенда.
Исходный запрос клиента:
GET /api/v1/products/SKU-1001
Настройка плагина proxy-rewrite:
{
"plugins": {
"proxy-rewrite": {
"regex_uri": [
"^/api/v1/products/(.*)",
"/internal/items/$1"
]
}
}
}
После преобразования upstream получит такой запрос:
GET /internal/items/SKU-1001
Здесь regex_uri сопоставляет исходный URI с регулярным выражением ^/api/v1/products/(.*). Часть пути после /api/v1/products/ попадает в переменную $1. Затем система подставляет это значение в новый URI /internal/items/$1.
В результате клиент продолжает использовать публичный путь /api/v1/products/SKU-1001, а бэкенд получает запрос в своём внутреннем формате: /internal/items/SKU-1001.