АрхитектураМикросервисы и интеграцииАрхитектор программных решений

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

Мобильное приложение должно собрать один экран из пяти микросервисов. Какой слой интеграции обычно вводят, чтобы клиент не зависел от их внутренних API?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Обычно вводят Backend for Frontend (BFF) — отдельный серверный слой, адаптированный к потребностям конкретного клиентского приложения. Он агрегирует данные нескольких микросервисов, преобразует их в модель экрана и скрывает от клиента внутреннюю структуру сервисов.

BFF не должен становиться владельцем бизнес-данных или дублировать бизнес-правила. Его основная ответственность — клиентская композиция, адаптация формата и управление особенностями взаимодействия с конкретным типом клиента.

Исторический контекст

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

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

Постановка проблемы

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

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

Подробное решение

BFF принимает запрос экрана, вызывает нужные микросервисы и возвращает клиенту специализированное представление данных. Например, он может объединить профиль пользователя, доступность товара и состояние доставки в один ответ, не заставляя приложение знать, где именно хранится каждая часть информации.

BFF обычно отвечает за:

  • агрегацию ответов нескольких сервисов;
  • преобразование внутренних моделей в модель конкретного клиента;
  • оптимизацию числа запросов и размера ответа;
  • адаптацию к возможностям мобильного, веб- или другого клиента;
  • согласованную обработку частичных отказов и таймаутов на уровне пользовательского сценария.

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

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

Основной компромисс — дополнительный серверный компонент. Он упрощает клиент и изолирует его от внутренних изменений, но сам становится частью критического пути и может превратиться в узкое место. Поэтому BFF масштабируют независимо, ограничивают его ответственность и не переносят в него доменную логику без необходимости.

Для частично недоступных сервисов BFF должен иметь явно определённую семантику: вернуть неполный экран, использовать допустимый кэш или сообщить об ошибке. Нельзя автоматически скрывать любой отказ, если из-за этого пользователь увидит данные, нарушающие бизнес-смысл.

Ситуация из практики

Мобильный экран заказа требовал данных о заказе, оплате, доставке и бонусах. Сначала приложение напрямую вызывало четыре сервиса. Это увеличивало задержку, усложняло обработку обновлений API и приводило к тому, что выпуск серверного изменения зависел от обновления мобильного клиента.

Рассматривались два варианта. Единый общий Gateway был проще в эксплуатации, но не решал задачу композиции экрана и сохранял часть клиентской связанности. Перенос данных в отдельную клиентскую базу уменьшал число запросов, но создавал сложность синхронизации и риск устаревших сведений.

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

Что кандидаты часто упускают

  1. Чем BFF отличается от простого прокси?

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

  1. Где должны находиться бизнес-правила, используемые при агрегации?

Правила, определяющие корректность бизнес-операции или состояние доменной сущности, должны оставаться во владеющих сервисах. BFF может определить, какие поля показать, как сгруппировать их для экрана или какой необязательный блок скрыть при ошибке, но не должен самостоятельно решать, считается ли платёж подтверждённым или заказ допустимо отправлять.

  1. Когда BFF лучше заменить локальной проекцией?

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