API Gateway для микросервисов на Java: полное руководство с кодом

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: почему вашему проекту нужен API Gateway?

Представьте, что вы архитектор, проектирующий современное здание. Вместо того чтобы прокладывать сотню отдельных дверей для каждой комнаты, вы делаете один центральный вход с ресепшеном, охраной и навигацией. Именно так работает API Gateway для Java сервисов — единая точка входа в вашу микросервисную архитектуру.

Когда я начинал работать с микросервисами на Java, первое, с чем столкнулся — хаос. Клиенты стучались напрямую в десятки сервисов, каждый со своим портом, авторизацией и форматом ошибок. Это было похоже на попытку управлять оркестром, где каждый музыкант играет свою партию, не слушая дирижера. Решение пришло именно в виде API шлюза Java.

В этой статье мы не просто поговорим о теории. Мы разберем живые примеры, напишем код на Java с использованием Spring Cloud Gateway, и вы сможете сразу применить эти знания в своем проекте. Готовы превратить хаос в порядок? Поехали.

Что такое API Gateway и зачем он нужен?

API Gateway (шлюз API) — это промежуточный слой между клиентами (веб-приложения, мобильные приложения, внешние сервисы) и вашими внутренними микросервисами. Он берет на себя всю "грязную работу": маршрутизацию, аутентификацию, балансировку, кэширование и мониторинг.

В экосистеме Java для этого чаще всего используют Spring Cloud Gateway — реактивный шлюз на основе Spring WebFlux, который работает невероятно быстро и гибко.

Основные задачи API Gateway в Java микросервисах:

  • Единая точка входа — все запросы идут через один хост:port
  • Маршрутизация — перенаправление запросов к нужным сервисам
  • Балансировка нагрузки — распределение трафика между инстансами
  • Безопасность — проверка JWT токенов, API ключей
  • Агрегация ответов — объединение данных из нескольких сервисов
  • Rate limiting — ограничение частоты запросов

Без API Gateway ваша архитектура напоминает спагетти-код: каждый клиент знает про каждый сервис. С ним — вы получаете чистую, управляемую систему.

Создаем API Gateway на Java с Spring Cloud Gateway

Давайте перейдем от теории к практике. Я покажу, как собрать рабочий API Gateway для Java сервисов буквально за 15 минут.

Шаг 1: Зависимости и настройка проекта

Создайте новый проект Spring Boot (рекомендую версию 3.x) и добавьте в pom.xml следующие зависимости:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- Для регистрации в Service Discovery (опционально) -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Не забудьте добавить BOM для Spring Cloud в <dependencyManagement>:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2023.0.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Шаг 2: Конфигурация маршрутов через YAML

Самый простой способ настроить маршрутизацию запросов Java — через application.yml. Вот пример, который перенаправляет запросы к сервисам пользователей и заказов:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Gateway-Version, 1.0

Что здесь происходит?

  • lb:// — указывает на балансировку нагрузки через Service Discovery (Eureka)
  • StripPrefix=1 — убирает первый сегмент пути (/api) перед отправкой в микросервис
  • RequestRateLimiter — ограничивает количество запросов (требует Redis)

Шаг 3: Программная настройка маршрутов (Java Config)

Иногда YAML недостаточно гибок. Например, нужно динамически менять маршруты или добавлять сложную логику. Для этого используем Java-конфигурацию:

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/users/**")
                .filters(f -> f
                    .stripPrefix(1)
                    .addRequestHeader("X-Gateway", "true")
                    .circuitBreaker(config -> config
                        .setName("userServiceCB")
                        .setFallbackUri("forward:/fallback/users")))
                .uri("lb://user-service"))
            
            .route("order-service", r -> r
                .path("/api/orders/**")
                .and().method("GET", "POST") // только GET и POST
                .filters(f -> f
                    .stripPrefix(1)
                    .retry(3)) // автоматический повтор при ошибках
                .uri("lb://order-service"))
            .build();
    }
}

Обратите внимание: мы добавили Circuit Breaker (предохранитель) для user-service. Если сервис падает, шлюз перенаправит запрос на fallback-эндпоинт. Это критически важно для надежности Java микросервисов.

Безопасность API Gateway: JWT и фильтры

API шлюз Java — идеальное место для централизованной проверки безопасности. Вместо того чтобы дублировать логику аутентификации в каждом сервисе, делаем это один раз.

Реализуем глобальный фильтр, который проверяет JWT токен:

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server                

Блоги

Рекомендаций по книгам