Files

26 lines
3.5 KiB
Markdown
Raw Permalink Normal View History

2026-10-21 05:08:05 +02:00
# D-022. Proxy: внутренние маршруты по хосту, домены из внутреннего эндпоинта
Статус: принято, 21.10.2026. Уточняет [D-005](D-005-multitenancy.md), пункт 3.
## Контекст
1. Языки, валюты, основной домен и индексация заданы у домена, а не у сайта. Страница, собранная на весь сайт, не знает, на каком зеркале её открыли: у зеркала со своим набором языков переключатель, `hreflang` и `canonical` были бы чужими.
2. Proxy в Next 16 работает отдельно от кода страниц, и документация Next запрещает полагаться на общие с ним модули и глобальные переменные. Payload внутри proxy создал бы второй экземпляр поверх общего `global._payload`.
## Решение
1. Во внутреннем маршруте — хост: `/m/{хост}/{язык}/{валюта}/…` — сайт, `/c/{хост}/{язык}/…` — кабинет, `/t/{хост}/…` — MiniApp. Сайт и настройки страница берёт из записи домена.
2. Proxy получает список активных доменов у `/svc/internal/domains` (заголовок `x-vx-internal-token` с `INTERNAL_TOKEN` из `.env`) и держит его в памяти 15 секунд. Устаревший список отдаётся сразу и обновляется в фоне. Правка домена в админке применяется в пределах 15 секунд.
3. Proxy свой, а не middleware next-intl: тот не умеет брать домены из базы, класть хост и валюту в путь и учитывать `X-Geo-Country`. next-intl используется для сообщений, форматирования и ссылок. Ботов определяет библиотека `isbot`.
4. `skipProxyUrlNormalize: true` в `next.config.ts`. Без него адрес запроса в proxy строится от `localhost`, а роутер Next слушает `127.0.0.1`, и любое переписывание считается внешним.
## Рассмотренные варианты
1. Код сайта во внутреннем маршруте, как было в 02 — ломается, как только у зеркала свой набор языков или валют.
2. Local API Payload прямо в proxy — второй экземпляр Payload и пул соединений в отдельной сборке, конфликт по `global._payload`.
3. Сброс кэша proxy из хука Payload — хук срабатывает до фиксации транзакции, и proxy мог бы перечитать старые данные; при кэше в 15 секунд выигрыш не нужен.
## Последствия
1. Статических вариантов страниц столько, сколько сочетаний «домен × язык × валюта»; сейчас у сайта по одному домену каждого типа.
2. Если эндпоинт недоступен, proxy работает по последнему полученному списку, а без него отвечает 503.