Шаблон: API Шлюз / Бэкэнды для Фронтендов
Контекст
Давайте представим, что вы создаете интернет-магазин, использующий шаблон микросервисной архитектруы, и реализуете страницу сведений о продукте. Вам необходимо разработать несколько версий пользовательского интерфейса сведений о продукте:
- Пользовательский интерфейс на основе HTML5/JavaScript для настольных и мобильных браузеров — HTML создается веб-приложением на стороне сервера.
- Нативные клиенты Android и iPhone — эти клиенты взаимодействуют с сервером через REST API.
Кроме того, интернет-магазин должен предоставлять сведения о продукте для сторонних приложений через REST API.
Пользовательский интерфейс для сведений о продукте может отображать много информации о продукте. Например, на странице сведений Amazon.com для POJO в действии отображается:
- Основная информация о книге, такая как название, автор, цена и т. д.
- Ваша история покупок книги
- Доступность
- Варианты покупки
- Другие товары, которые часто покупают вместе с этой книгой
- Другие товары, купленные клиентами, купившими эту книгу
- Отзывы клиентов
- Рейтинг продавцов
- …
Поскольку интернет-магазин использует шаблон архитектуры микросервиса, данные о товарах распределяются по нескольким сервисам. Например,
- Служба информации о продукте (Product Info Service) - основная информация о продукте, такая как название, автор
- Служба ценообразования (Pricing Service) - цена продукта
- Служба заказа (Order service) - история покупок для продукта
- Служба инвентаризации (Inventory service) - доступность продукта
- Сервис отзывов (Review Service) - отзывы клиентов…
Следовательно, код, который отображает сведения о продукте, должен получать информацию от всех этих служб.
Проблема
Как клиенты приложения на основе микросервисов получают доступ к отдельным службам?
Требуется преодолеть
- Степень детализации API, предоставляемая микросервисами, часто отличается от того, что нужно клиенту. Микросервисы обычно предоставляют разрозненные API, а это означает, что клиентам необходимо взаимодействовать с несколькими сервисами. Например, как описано выше, клиенту, которому нужны сведения о продукте, необходимо получить данные из многочисленных служб.
- Разным клиентам нужны разные данные. Например, браузерная настольная версия страницы сведений о продукте обычно более сложная, чем мобильная версия.
- Производительность сети отличается для разных типов клиентов. Например, мобильная сеть обычно намного медленнее и имеет гораздо большую задержку, чем немобильная сеть. И, конечно же, любая WAN намного медленнее, чем LAN. Это означает, что собственный мобильный клиент использует сеть с очень разными характеристиками производительности, чем локальная сеть, используемая веб-приложением на стороне сервера. Веб-приложение на стороне сервера может делать несколько запросов к серверным службам, не влияя на взаимодействие с пользователем, тогда как мобильный клиент может делать только малую часть.
- Количество экземпляров службы и их расположение (хост+порт) изменяется динамически.
- Разделение на службы может меняться со временем и должно быть скрыто от клиентов.
- Службы могут использовать разнообразный набор протоколов, некоторые из которых могут быть несовместимы с веб.
Решение
Внедрите API шлюз, который является единой точкой входа для всех клиентов. Шлюз API обрабатывает запросы одним из двух способов. Некоторые запросы просто проксируются/маршрутизируются в соответствующую службу. Другие запросы обрабатываются, разветвляясь на несколько служб.
Вместо того, чтобы предоставлять универсальный API-интерфейс, API-шлюз может предоставлять разные API для каждого клиента. Например, шлюз к API Netflix запускает код адаптера для конкретного клиента, который предоставляет каждому клиенту тот API, который лучше всего соответствует его требованиям.
Шлюз к API может также обеспечивать безопасность, например проверять, авторизован ли клиент для выполнения запроса.
Вариант: Бэкенды для фронтендов
Вариантом этого шаблона является шаблон Backends for frontends. Он определяет отдельный API шлюз для каждого типа клиентов.
В этом примере есть три типа клиентов: веб-приложение, мобильное приложение и внешнее стороннее приложение. Существует три разных API шлюза. Каждый из них предоставляет API для своего клиента.
Примеры
Итоговый контекст
Использование API шлюза имеет следующие преимущества:
- Изолирует клиентов от того, как приложение разделено на микросервисы.
- Изолирует клиентов от проблемы определения местоположения экземпляров службы.
- Предоставляет оптимальный API для каждого клиента
- Уменьшает количество запросов/приёмов-передач(round-trips). Например, API шлюз позволяет клиентам извлекать данные из нескольких служб за один round-trip. Меньшее количество запросов также означает меньшие накладные расходы и улучшает взаимодействие с пользователем. API Шлюз просто необходим для мобильных приложений.
- Упрощает клиент, перемещая логику вызова нескольких служб с клиента на шлюз API.
- Переводит из «стандартного» общедоступного веб-протокола API в любые протоколы, используемые внутри компании.
Шаблон API шлюза имеет некоторые недостатки:
- Повышенная сложность — API шлюз — это еще одна под часть, которую необходимо разрабатывать, развертывать и управлять
- Увеличение времени отклика из-за дополнительного сетевого перехода через API-шлюз, однако для большинства приложений стоимость дополнительного кругового пути незначительна.
- Как реализовать API-шлюз? Лучше всего подходит, реактивный/ управляемый событиями подход, если шлюз должен масштабироваться для обработки высоких нагрузок. В JVM библиотеки на основе NIO, такие как Netty, Spring Reactor и т. д., имеют смысл. NodeJS — еще один вариант.
Связанные шаблоны
- Шаблон микросервисной архитектуры создает потребность в этом шаблоне.
- Шлюз API должен использовать шаблон обнаружения на стороне клиента или шаблон обнаружения на стороне сервера для маршрутизации запросов к доступным экземплярам службы.
- Шлюз API может аутентифицировать пользователя и передать Access Token , содержащий информацию о пользователе, службам.
- Шлюз API будет использовать автоматический выключатель (Circuit Breaker) для вызова служб.
- Шлюз API часто реализует шаблон API-композиции.
Примеры использования
Пример приложения
См. шлюз API, часть примера приложения моего шаблона микросервисов. Он реализован с использованием Spring Cloud Gateway.