Как указать роуты для API с использованием API Gateway и микросервисов
Что проверяют
Понимаете ли вы, какую работу берёт на себя шлюз, и умеете ли настроить маршрутизацию в Spring Cloud Gateway. Следом спрашивают, откуда шлюз узнаёт адреса сервисов и где проверять авторизацию.
Как отвечать
Роут в Spring Cloud Gateway состоит из id, адреса назначения, предикатов (условия совпадения) и фильтров (изменения запроса и ответа). Пример на Java DSL:
@Bean
RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("orders", r -> r.path("/api/v1/orders/**")
.filters(f -> f.stripPrefix(2))
.uri("lb://order-service"))
.build();
}Что здесь важно:
lb://order-service: адрес берётся не из конфига, а из service discovery (Eureka, Consul) через Spring Cloud LoadBalancer. В Kubernetes часто хватаетhttp://order-service:8080, балансирует сам сервис кластера;- предикаты:
Path,Method,Header,Host. По заголовку можно увести часть трафика на новую версию; - фильтры:
StripPrefixиRewritePathдля путей (здесь/api/v1/orders/42уйдёт в сервис как/orders/42),RequestRateLimiterна Redis,CircuitBreakerс Resilience4j,Retry; - авторизация: шлюз проверяет JWT один раз через Spring Security (
oauth2ResourceServer) и пробрасывает токен дальше, но проверку прав на конкретные данные оставляют сервисам; - версионирование: версия в пути (
/api/v1) или в заголовке.
Упомяните, что у Spring Cloud Gateway есть реактивный вариант на WebFlux и сервлетный на Spring MVC. Вне Spring роль шлюза играют Kong, Nginx или Ingress-контроллер в Kubernetes.
Где спотыкаются
Хардкодят http://localhost:8081 в роутах. На проде у сервиса несколько инстансов, и без discovery или DNS кластера балансировки нет.
Кладут в шлюз бизнес-логику, например проверку, может ли пользователь видеть конкретный заказ. Это знание сервиса заказов, а шлюз тогда приходится деплоить при каждой правке любого сервиса.
Путаются в путях. Сервис ждёт /orders/42, получает /api/v1/orders/42 и отвечает 404. Или общий роут /api/** стоит раньше конкретного и перехватывает его запросы: срабатывает первый подходящий по порядку.