Редиректы

Как вернуть клиенту редирект на другой URI или перенаправить его с HTTP на HTTPS.

Что это

Редирект в данном контексте — это ответ Application Delivery Controller, что нужный ресурс находится по другому адресу.

Система не передаёт запрос на upstream, вместо этого она возвращает клиенту HTTP-ответ с кодом редиректа и заголовком Location. Клиент получает этот ответ и повторяет запрос уже по новому адресу.

Как работает

  1. Клиент отправляет запрос.

  2. Наша система получает запрос и сопоставляет его с Route, в котором настроен плагин redirect.

  3. Система проверяет настройки плагина.

    Если настроен uri, система сразу формирует редирект на настроенный вами URI.

    Если настроен regex_uri, система сопоставляет исходный URI с регулярным выражением. Если URI подходит под выражение, система формирует новый URI по шаблону. Если не подходит — запрос будет передан на upstream.

    Если настроен http_to_https, система перенаправляет HTTP-запрос на HTTPS-адрес с тем же URI.

  4. Система возвращает клиенту HTTP-ответ с кодом из ret_code и заголовком Location.

  5. Клиент получает редирект и делает запрос к адресу из Location.

Когда пригодится

Предположим, у вас был публичный эндпоинт /api/v1/catalo g, но теперь клиенты должны перейти на новый путь /api/v2/catalog. Старый эндпоинт планируется отключить, но сделать это сразу нельзя: часть клиентов ещё отправляет запросы на прежний адрес.

На переходный период вы добавляете redirect и настраиваете редирект со старого URI на новый. В результате клиент, который обращается к /api/v1/catalog, получает ответ с кодом 301 или 302 и заголовком Location: /api/v2/catalog. Так клиенты, которые ещё не обновили интеграцию, смогут продолжить работу и одновременно увидят новый адрес, на который нужно перейти.

Какой плагин используется

redirect

Атрибуты плагина

Атрибут Тип Обязательный Значение по умолчанию Допустимые значения Что задаёт

http_to_https

boolean

Нет

false

true, false

Перенаправляет HTTP-запрос на HTTPS с тем же URI. Возвращает код 301. Query string из исходного URI также попадёт в заголовок Location.

uri

string

Нет

URI или URL; можно использовать NGINX variables

Адрес, на который нужно перенаправить клиента. Например, /docs/index.html, $uri/index.html, ${uri}/index.html, https://example.com/docs. Если указать несуществующую переменную, она будет считаться пустой строкой.

regex_uri

array
[string]

Нет

Массив из двух строк

Правило редиректа по регулярному выражению. Первый элемент — регулярное выражение для исходного URI, второй — новый URI. Найденные части можно использовать через $1, $2, $3 и т.д.

Например, значение ["^/api/v1/(.*)", "/api/v2/$1"] перенаправит запрос /api/v1/catalog на /api/v2/catalog.

ret_code

integer

Нет

302

От 200

HTTP-код ответа. Для редиректов обычно используют 301, 302, 307 или 308.

encode_uri

boolean

Нет

false

true, false

Кодирует URI в заголовке Location по правилам RFC3986.

append_query_
string

boolean

Нет

false

true, false

Добавляет query string из исходного запроса в заголовок Location. Если в настроенном uri или regex_uri уже есть query string, параметры исходного запроса будут добавлены через &.

Что важно учесть

Из трёх атрибутов http_to_https, uri и regex_uri можно настроить только один; каждый из них — это отдельный способ сформировать редирект.

http_to_https нельзя использовать вместе с append_query_string.

Если включён http_to_https, система возвращает код 301 и формирует HTTPS-адрес с тем же URI; порт в Location будет зависеть от конфигурации HTTPS в системе; если отдельная конфигурация не задана, используется 443. Query string исходного запроса будет сохранена в Location.

Если используется regex_uri и исходный URI не подходит под регулярное выражение, redirect не сработает. В этом случае запрос будет передан на upstream.

Если вы уже добавили query string через переменную, например $request_uri, не включайте append_query_string: параметры могут продублироваться. Переменная $request_uri уже содержит путь вместе с query string, а append_query_string добавит эти же параметры в Location ещё раз.

Если в uri используется переменная, которой не существует, система не вернёт ошибку. Такая переменная будет заменена на пустую строку.

Как подключить плагин

Через 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": {
      "redirect": {
        "...": "ваши настройки плагина"
      }
    },
    "upstream": {
      "...": "ваши настройки upstream"
    }
  }'

Здесь id — идентификатор Route, uri — путь, по которому запрос попадает в Route, plugins.redirect содержит конфигурацию плагина, а upstream — настройки бэкенд-серверов.

Через UI

  1. Откройте раздел Маршруты и нажмите + Добавить.

  2. В настройках маршрута (Route) перейдите в раздел Плагины.

  3. Нажмите + Добавить и выберите redirect.

  4. Укажите конфигурацию плагина как JSON-объект.

  5. Сохраните созданный маршрут (Route). Он будет добавлен с подключённым плагином.

Пример конфигурации плагина

В этом примере система перенаправляет клиента со старого публичного URI /api/v1/catalog на новый — /api/v2/catalog.

Исходный запрос клиента:

GET /api/v1/catalog?category=books

Настройка плагина redirect:

{
  "plugins": {
    "redirect": {
      "uri": "/api/v2/catalog",
      "ret_code": 301,
      "append_query_string": true,
      "encode_uri": true
    }
  }
}

После обработки клиент получит ответ:

HTTP/1.1 301 Moved Permanently
Location: /api/v2/catalog?category=books

Здесь uri задаёт новый адрес, который попадёт в заголовок Location, ret_code задаёт HTTP-код редиректа, append_query_string сохраняет query-параметры из исходного запроса, а encode_uri кодирует URI в заголовке Location по правилам RFC3986.

Если клиент повторит запрос по адресу из Location, он обратится уже к новому URI:

GET /api/v2/catalog?category=books