Автор статьи: Сергей Прощаев @sproshchaev
Руководитель направления Java‑разработки в FinTech
Введение
В современном мире цифровых сервисов и микросервисной архитектуры, предоставление внешнего API становится критически важной задачей для любого бизнеса.
Хорошо спроектированный и надежный API — это ворота, через которые ваши данные и функциональность взаимодействуют с внешним миром: мобильными приложениями, веб‑сайтами, партнерскими сервисами и даже внутренними клиентами.
Однако, создание «идеального» API — это не просто предоставление эндпоинтов. Это комплексный процесс, который включает в себя не только технические аспекты, но и стратегическое проектирование, обеспечение безопасности, управление трафиком и масштабируемость. Именно здесь на помощь приходит API Gateway — ключевой компонент, который выступает в роли единой точки входа для всех запросов к нашей системе.
Что такое API Gateway?
API Gateway — это сервис, который выступает в роли посредника между клиентами и внутренними сервисами, входящими в распределенную архитектуру.
Можно выделить основные функции API Gateway, которые включают в себя:
-
Маршрутизацию: в рамках которой мы направляем входящие запросы к соответствующему внутреннему сервису. При этом внешнему клиенту не видит весь путь, по которому будет проходить наш запрос после API Gateway
-
Агрегацию: через которую мы можем производить объединение данных из нескольких внутренних сервисов и формировать один ответ для внешнего клиента.
-
Аутентификацию и авторизацию: здесь очевидно, через API Gateway должны проходить запросы только от аутентифицированных клиентов. Поэтому в этой части API Gateway проводит проверку подлинности и прав доступа каждого внешнего клиента.
-
Ограничение скорости (Rate Limiting): если число внешних запросов превышает порог допустимого значения для нашего бэкэнда, то API Gateway может встать на защиту наших внутренних сервисов от чрезмерной нагрузки и ограничить входящий трафик.
-
Кэширование: через использование кэшей внутри API Gateway мы можем повышать производительность, сохраняя результаты часто запрашиваемых данных, которые не изменяются со временем.
-
Логирование и мониторинг: API Gateway может организовывать сбор метрик и логов для анализа производительности, что позволит создать единую точку для выявления проблем.
-
Трансформацию: иногда в функционале API Gateway производится преобразование форматов данных или протоколов для обеспечения совместимости.
-
Управление версиями: как единая точка входа API Gateway может осуществлять контроль над различными версиями API.
Поэтому при использовании API Gateway мы значительно упрощаем клиента, потому как клиент взаимодействует только с одним единым интерфейсом, а не с множеством микросервисов.
Помимо этого у нас происходит изоляция внутренней архитектуры и внутренние сервисы могут развиваться независимо, без необходимости изменять внешний API, так как это на себя возьмет API Gateway.
И за счет того, что мы создаем централизованную точка контроля доступа и фильтрации запросов, повышается безопасность всей распределенной системы.
Для того, чтобы понять как все устроено — давайте разберем небольшой учебный пример, на котором разберем как все устроено.
Пример простейшего API Gateway на практике
Давайте представим, что наша распределенная система, входящая в бэкэнд, состоит из двух сервисов: user‑service и order‑service. Для того, чтобы управлять запросами извне — перед ними мы установим API Gateway.
И любой внешний клиент, который планирует получить информацию о пользователях или заказах — должен сформировать запрос к 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:
-
11 сентября в 20:00 — «API Gateway и не только: шаги к идеальной архитектуре внешних API»
-
17 сентября в 20:00 — «Паттерны отказоустойчивости и масштабируемости микросервисной архитектуры»
Кроме того, вы можете пройти бесплатное вступительное тестирование — чтобы узнать свой уровень знаний и навыков для поступления на курс.
ссылка на оригинал статьи https://habr.com/ru/articles/944940/
Добавить комментарий