Микросервисы
July 9, 2023

Шаблон: 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, часть примера приложения моего шаблона микросервисов. Он реализован с использованием Spring Cloud Gateway.

Источник: https://microservices.io/patterns/apigateway.html