Что скрывает ваш API Gateway

от автора

Автор статьи: Сергей Прощаев @sproshchaev
Руководитель направления Java‑разработки в FinTech

Введение

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

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

Однако, создание «идеального» API — это не просто предоставление эндпоинтов. Это комплексный процесс, который включает в себя не только технические аспекты, но и стратегическое проектирование, обеспечение безопасности, управление трафиком и масштабируемость. Именно здесь на помощь приходит API Gateway — ключевой компонент, который выступает в роли единой точки входа для всех запросов к нашей системе.

Что такое API Gateway?

API Gateway — это сервис, который выступает в роли посредника между клиентами и внутренними сервисами, входящими в распределенную архитектуру.

Можно выделить основные функции API Gateway, которые включают в себя:

  1. Маршрутизацию: в рамках которой мы направляем входящие запросы к соответствующему внутреннему сервису. При этом внешнему клиенту не видит весь путь, по которому будет проходить наш запрос после API Gateway

  2. Агрегацию: через которую мы можем производить объединение данных из нескольких внутренних сервисов и формировать один ответ для внешнего клиента.

  3. Аутентификацию и авторизацию: здесь очевидно, через API Gateway должны проходить запросы только от аутентифицированных клиентов. Поэтому в этой части API Gateway проводит проверку подлинности и прав доступа каждого внешнего клиента.

  4. Ограничение скорости (Rate Limiting): если число внешних запросов превышает порог допустимого значения для нашего бэкэнда, то API Gateway может встать на защиту наших внутренних сервисов от чрезмерной нагрузки и ограничить входящий трафик.

  5. Кэширование: через использование кэшей внутри API Gateway мы можем повышать производительность, сохраняя результаты часто запрашиваемых данных, которые не изменяются со временем.

  6. Логирование и мониторинг: API Gateway может организовывать сбор метрик и логов для анализа производительности, что позволит создать единую точку для выявления проблем.

  7. Трансформацию: иногда в функционале API Gateway производится преобразование форматов данных или протоколов для обеспечения совместимости.

  8. Управление версиями: как единая точка входа API Gateway может осуществлять контроль над различными версиями API.

Поэтому при использовании API Gateway мы значительно упрощаем клиента, потому как клиент взаимодействует только с одним единым интерфейсом, а не с множеством микросервисов.

Помимо этого у нас происходит изоляция внутренней архитектуры и внутренние сервисы могут развиваться независимо, без необходимости изменять внешний API, так как это на себя возьмет API Gateway.

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

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

Пример простейшего API Gateway на практике

Давайте представим, что наша распределенная система, входящая в бэкэнд, состоит из двух сервисов: user‑service и order‑service. Для того, чтобы управлять запросами извне — перед ними мы установим API Gateway.

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

Рис.1 Пример простого API Gateway с двумя сервисами

Рис.1 Пример простого API Gateway с двумя сервисами

На рис. 1 изображена схема нашей распределенной системы.

Структура проекта

В состав нашего учебного проекта будет входить три модуля:

api-gateway-demo/ ├── api-gateway/            ├── user-service/          └── order-service/ 

Модуль api‑gateway будет содержать реализацию API Gateway на базе Spring Cloud Gateway. Именно он будет отвечать за прием и дальнейшую маршрутизацию всех вызовов от внешних клиентов к двум нашим сервисам.

Модуль user‑service представляет собой микросервис для работы с пользователями.

И наконец order‑service будет содержать логику микросервиса для работы с заказами, который принимает запросы и возвращает информацию о номере заказа, числе позиций, входящих в заказ и идентификаторе клиента, с которым связан данный заказ.

Для лучшего понимания настроек API Gateway мы сначала рассмотрим реализацию сервисов, а затем шлюза.

Реализация user‑service

Подключим зависимости в build.gradle:

dependencies {    implementation 'org.springframework.boot:spring-boot-starter-web' }

Создадим application.yml:

server:  port: 8081  spring:  application:    name: user-service

И напишем простейший UserController, который эмулирует работу слоя сервисов и репозитория:

@RestController @RequestMapping("/users") public class UserController {     @GetMapping("/{id}")    public Map<String, Object> getUser(@PathVariable String id) {    // В реальном приложении здесь был бы вызов сервиса/репозитория        return Map.of(                "id", id,                "name", "User " + id,                "email", "user" + id + "@example.com"        );    } }

И наконец главный класс UserServiceApp:

@SpringBootApplication public class UserServiceApp {     public static void main(String[] args) {        SpringApplication.run(UserServiceApp.class, args);    }  }

Реализация order‑service

Из зависимостей в приложении order‑service в build.gradle будет аналогичный стартер:

dependencies {    implementation 'org.springframework.boot:spring-boot-starter-web' }

В application.yml у нас находится только порт 8082 и имя сервиса order‑service:

server:  port: 8082  spring:  application:    name: order-service

Класс контроллера OrderController формирует логику эндпоинта /orders/{id}:

@RestController @RequestMapping("/orders") public class OrderController {     @GetMapping("/{id}")    public Map<String, Object> getOrder(@PathVariable String id) {    // В реальном приложении здесь был бы вызов сервиса/репозитория        return Map.of(                "id", id,                "userId", "123",                "product", "Product " + id,                "quantity", 1        );    } }

И точка входа в приложение — класс OrderServiceApp:

@SpringBootApplication public class OrderServiceApp {    public static void main(String[] args) {        SpringApplication.run(OrderServiceApp.class, args);    } }

Реализация api-gateway

И теперь перейдем к главному нашему компоненту распределенной системы — API Gateway на базе Spring Cloud Gateway.

Зависимости в build.gradle:

dependencies {     implementation     'org.springframework.cloud:spring-cloud-starter-gateway' }

В api‑gateway самым основным будет конфигурационный файл application.yml, который мы разберем по частям.

Начало идентичное, как в первых двух сервисах — порт шлюза для внешних клиентов и имя приложения:

server:  port: 8080  spring:  application:    name: api-gateway

Далее идет секция настройки spring‑cloud‑gateway‑routes и первый маршрут определяет куда перенаправлять запросы от внешних сервисов в адрес сервиса пользователей user‑service:

spring:  application:    name: api-gateway  cloud:    gateway:      routes:        - id: user-service          uri: http://localhost:8081          predicates:            - Path=/api/users/**          filters:            - StripPrefix=1 

Параметр StripPrefix=1 в API Gateway удаляет для user‑service первый сегмент пути /api из запроса и путь после фильтра остается: /users/123.

Второй блок роутинга содержит настройки для order‑service и в нем мы должны определить как и куда пройдут запросы от внешних клиентов к микросервису заказов:

spring:  application:    name: api-gateway  cloud:    gateway:      routes:        …         - id: order-service          uri: http://localhost:8082          predicates:            - Path=/api/orders/**          filters:            - StripPrefix=1 

Параметр StripPrefix=1 задает для order‑service путь после фильтра: /api/orders/456, который преобразует в /orders/456.

Главный класс ApiGatewayApp содержит только:

@SpringBootApplication public class ApiGatewayApp {    public static void main(String[] args) {        SpringApplication.run(ApiGatewayApp.class, args);    } }

Всю остальную логику API Gateway за нас сделает Spring.

Тестирование

Теперь самое интересное. Давайте запустим все наших три сервиса и посмотрим как изменился их вызов.

Из нашей внутренней сети, которая не доступна для внешних клиентов мы можем вызвать user‑service:

curl -v http://localhost:8081/users/123

И получить ответ:

{"email":"user123@example.com","name":"User 123","id":"123"}

И можем вызвать order‑service:

curl -v http://localhost:8082/orders/456

И получим:

{"id":"456","product":"Product 456","userId":"123","quantity":1}

А как теперь можно достучаться до этих сервисов извне со стороны внешних клиентов, используя API Gateway?

Все внешние клиенты теперь будут обращаться на единственный эндпоинт API Gateway, который будет доступен:

curl -v http://localhost:8080/api/users/123

Ответ будет таким же, как и при прямом вызове user‑service:

{"email":"user123@example.com","id":"123","name":"User 123"}

А при вызове order‑service:

curl -v http://localhost:8080/api/orders/456

Мы получим:

{"id":"456","product":"Product 456","userId":"123","quantity":1}

Мы видим, что API Gateway объединил эндпоинты двух сервисов в один и сформировал единую точку маршрутизации для внешних клиентов.

Полный пример этого учебного проекта находится в репозитории GitHub и доступен по ссылке https://github.com/sproshchaev/api‑gateway‑demo.

Заключение

Понимание принципов работы API Gateway и умение эффективно его использовать является критически важным навыком для современного архитектора и бэкенд‑разработчика, поскольку это ключевой компонент в архитектуре распределенных систем и микросервисов.

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

Владение этим знанием напрямую влияет на возможность создания масштабируемых, надежных и высокопроизводительных API, отвечающих современным требованиям.


В материале мы рассмотрели значение API Gateway и его место в микросервисной архитектуре. Именно такие фундаментальные темы позволяют лучше понимать устройство распределённых систем и принимать обоснованные проектные решения.

Чтобы глубже разобраться в практических аспектах построения архитектуры, приглашаем вас на бесплатные уроки курса Software Architect:

Кроме того, вы можете пройти бесплатное вступительное тестирование — чтобы узнать свой уровень знаний и навыков для поступления на курс.


ссылка на оригинал статьи https://habr.com/ru/articles/944940/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *