Найти в Дзене
Lyakhov Eugene

Backend for Frontend

Backend for Frontend (BFF) — это архитектурный паттерн, при котором для каждого пользовательского интерфейса (веб-приложение, мобильное приложение, десктоп, умные часы и т.д.) создаётся отдельный серверный компонент. Этот компонент выступает прослойкой между клиентом и общей серверной инфраструктурой (микросервисами, монолитом, внешними API). Основная идея BFF заключается в том, чтобы перенести логику, специфичную для конкретного клиента, на сервер, приближенный к клиенту, тем самым упрощая клиентское приложение и оптимизируя взаимодействие с ним. В классической многоуровневой архитектуре все клиенты обращаются к одному и тому же бэкенду. Это приводит к ряду проблем: BFF решает эти проблемы, предоставляя каждому клиенту свой "персональный" бэкенд. Представим крупный маркетплейс. Есть веб-версия для десктопа, мобильное приложение и приложение для умных часов. Клиенты: веб-плеер, мобильное приложение, телевизоры, игровые консоли. Клиенты: веб-банк, мобильный банк, терминалы самообслужи
Оглавление

Backend for Frontend (BFF) — что это такое?

Backend for Frontend (BFF) — это архитектурный паттерн, при котором для каждого пользовательского интерфейса (веб-приложение, мобильное приложение, десктоп, умные часы и т.д.) создаётся отдельный серверный компонент. Этот компонент выступает прослойкой между клиентом и общей серверной инфраструктурой (микросервисами, монолитом, внешними API).

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

Зачем нужен BFF?

В классической многоуровневой архитектуре все клиенты обращаются к одному и тому же бэкенду. Это приводит к ряду проблем:

  • Избыточность данных: мобильному приложению могут не требоваться те же данные, что веб-версии, но API возвращает всё.
  • Разные форматы и протоколы: веб может работать с REST, а мобильному приложению удобнее GraphQL.
  • Множественные запросы: для отображения одной страницы клиенту приходится делать несколько вызовов к разным микросервисам.
  • Сложность клиентского кода: логика агрегации, фильтрации и преобразования данных ложится на клиент.

BFF решает эти проблемы, предоставляя каждому клиенту свой "персональный" бэкенд.

Преимущества BFF (детально)

1. Оптимизация под конкретный клиент

  • Разные требования к данным: Веб-версия может показывать детальную информацию, а мобильная — только самую важную. BFF может отдавать ровно тот набор полей, который нужен клиенту, без лишней информации.
  • Разные форматы: Например, веб-клиент ожидает JSON, а мобильное приложение — более компактный формат (MessagePack, Protocol Buffers). BFF может выполнять трансформацию.
  • Разные протоколы: Один BFF может предоставлять REST API, другой — GraphQL или gRPC-Web.

2. Улучшение производительности клиента

  • Агрегация запросов: Вместо 5–10 вызовов от клиента к разным микросервисам, BFF делает эти вызовы параллельно на сервере и возвращает один объединённый ответ. Это уменьшает задержки и снижает нагрузку на клиентское устройство.
  • Кэширование: BFF может кэшировать ответы от нижележащих сервисов, ускоряя повторные запросы от клиента.
  • Сжатие данных: BFF может применять сжатие (gzip, brotli) к ответам, экономя трафик клиента.
  • Предварительная загрузка (prefetch): BFF может заранее подготавливать данные, которые могут понадобиться клиенту в ближайшее время.

3. Упрощение клиентского кода

  • Клиентское приложение становится тоньше: вся логика по сборке данных из разных источников, их фильтрации и преобразованию уходит на сервер. Разработчики клиента могут сосредоточиться на интерфейсе и взаимодействии с пользователем.
  • Отсутствие необходимости в сложных state-менеджерах на клиенте для координации множества запросов.

4. Безопасность

  • Сокрытие внутренней архитектуры: Клиент видит только BFF, а не внутренние микросервисы. Это снижает риск атак на внутренние сервисы.
  • Централизованная аутентификация и авторизация: BFF может выступать единым входом для клиента. Он проверяет токены, куки, API-ключи и передаёт контекст безопасности дальше (например, через заголовки).
  • Валидация и санитизация входящих данных: BFF может проверять входные запросы на корректность, защищая нижележащие сервисы от некорректных или вредоносных данных.
  • Дополнительный уровень защиты от DDoS, подмены запросов (CSRF) и других атак.

5. Автономность команд

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

6. Изоляция изменений в бэкенде

  • Если меняется внутренний API (например, один микросервис заменяется другим), изменения можно отработать на уровне BFF, не требуя обновления клиентских приложений. Клиент продолжает получать данные в прежнем формате.
  • Легче проводить A/B тестирование и постепенный rollout новых версий.

7. Адаптация к сетевым условиям

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

Примеры проектов с реализацией BFF

1. Интернет-магазин (e-commerce)

Представим крупный маркетплейс. Есть веб-версия для десктопа, мобильное приложение и приложение для умных часов.

  • Веб-BFF: Отдаёт расширенные данные по товарам (описания, характеристики, отзывы, рекомендации), поддерживает сложные фильтры и пагинацию. API может быть REST.
  • Мобильный BFF: Оптимизирован для работы с сенсорным экраном. Отдаёт только ключевые поля (название, цена, рейтинг, главное изображение). Использует GraphQL, чтобы клиент мог запросить ровно то, что нужно. Также может агрегировать данные о корзине, избранном, персональных предложениях.
  • BFF для умных часов: Отдаёт минимальный набор (название товара, цена, возможность быстрого заказа по голосу). Протокол может быть упрощённым (например, WebSocket для быстрых обновлений).

2. Потоковый сервис (Spotify, Netflix)

Клиенты: веб-плеер, мобильное приложение, телевизоры, игровые консоли.

  • BFF для телевизора: Должен учитывать особенности навигации с пульта, отдавать крупные постеры, поддерживать протоколы типа DIAL или Cast.
  • BFF для мобильного приложения: Оптимизирует загрузку контента при переключении между Wi-Fi и мобильной сетью, может кэшировать плейлисты и рекомендации.
  • BFF для веб-плеера: Обеспечивает низкую задержку при переключении треков, поддержку DRM, интеграцию с браузерными API.

3. Банковское приложение

Клиенты: веб-банк, мобильный банк, терминалы самообслуживания.

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

4. Социальная сеть

Клиенты: веб, мобильное приложение (iOS, Android), десктопное приложение (Electron).

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

5. Классическая микросервисная архитектура (Azure)


В этом примере у нас есть два клиента: мобильное приложение и десктопный веб-клиент.

  • Проблема: Мобильное приложение хочет получать данные маленькими порциями (1 страница), а десктоп может загружать данные агрегированно (5 страниц сразу).
  • Решение:
    Входящий трафик проходит через Azure API Management (шлюз). Он проверяет токены в Microsoft Entra ID и логирует все в Azure Monitor .
    Затем запросы распределяются:
    Запрос с мобильного телефона идет в
    Azure Function "Mobile BFF".
    Запрос с десктопа идет в
    Azure Function "Desktop BFF".
    Mobile BFF ходит в микросервисы, забирает только 1 страницу и кэширует её.
    Desktop BFF агрегирует данные из нескольких микросервисов и отдает один большой ответ.
    Результат: Мобильный клиент экономит трафик, а десктопный получает всю мощь без потери скорости.

6. BFF для безопасности SPA (Duende + ASP.NET Core)


Представьте современное React-приложение (SPA), которому нужно общаться с API.

  • Проблема: Хранить секретный ключ доступа (access token) в JavaScript-коде React-приложения опасно. Любая XSS-уязвимость может привести к краже токена .
  • Решение:
    Создается хост на ASP.NET Core, который включает библиотеку Duende.BFF .
    Браузер обращается по адресу /bff/login, инициируя вход через
    IdentityServer.
    IdentityServer возвращает токен, но он сохраняется в BFF-хос. Браузеру выдается только
    HttpOnly cookie.
    При вызове API (например, /api/weather или прокси на внешний API) браузер просто прикрепляет эту куку. BFF-хост сам подкладывает нужный токен в запрос к защищенному API.
    Результат: Токен никогда не покидает сервер. Это делает приложение максимально защищенным от кражи учетных данных. https://duendesoftware.com/blog/20210326-bff

7. Учебный проект FitFriends (NestJS + React)


Это пример из реальной практики разработчика, выложенный на GitHub .

  • Стек: Бэкенд на NestJS (микросервисы), фронтенд на React.
  • Реализация:
    Приложение состоит из нескольких микросервисов: users, trainings, gyms, notify.
    Для того чтобы React-фронтенду не приходилось самому собирать данные из 4 разных источников, в архитектуру добавлен отдельный микросервис bff.
    React-приложение общается только с bff, а тот уже агрегирует данные из всех остальных сервисов и отдает готовый результат.
    Результат: Фронтенд не знает о сложной внутренней архитектуре, он просто дергает свой личный API.
    https://github.com/Ciberian/FitFriends-Fullstack

8. BFF на AWS (Serverless)

  • Сценарий: Микро-фронтенды (Micro-frontends) на AWS.
  • Решение: AWS рекомендует для каждого микро-фронтенда создавать свой BFF, который занимается авторизацией, агрегацией данных и трансформацией .
  • Инструменты: Такой BFF можно реализовать через AWS AppSync (GraphQL), набор Lambda-функций или в контейнерах на ECS/EKS.
  • Результат: Уменьшение количества вызовов с клиента ("чаттинг") и упрощение логики на стороне браузера. https://docs.aws.amazon.com/prescriptive-guidance/latest/micro-frontends-aws/api-integration-data-fetching.html

Адаптация, безопасность и производительность клиента

Адаптация

BFF обеспечивает адаптацию данных и логики под конкретный клиент:

  • Трансформация данных: изменение структуры JSON, переименование полей, объединение данных из нескольких источников.
  • Версионирование: разные версии мобильного приложения могут обращаться к разным версиям BFF (или BFF поддерживает версионность API).
  • Поддержка разных устройств: BFF может определять тип клиента по заголовку User-Agent и подбирать оптимальный размер изображений, количество элементов в списке и т.д.
  • Локализация и интернационализация: BFF может возвращать уже переведённые строки или предоставлять данные для разных языков без нагрузки на клиент.

Безопасность

  • Аутентификация: BFF проверяет подлинность клиента (JWT, OAuth2, сессионные куки). Он может выступать OAuth2-клиентом, получая токены от сервера авторизации.
  • Авторизация: BFF проверяет права доступа к конкретным данным или операциям для данного пользователя и клиента.
  • Защита от атак:
    Лимитирование запросов (rate limiting) на уровне BFF для конкретного клиента.
    Валидация входных данных (SQL-инъекции, XSS).
    Проверка Content-Type и размеров запросов.
    Шифрование трафика (HTTPS).
  • Сокрытие внутренней инфраструктуры: BFF скрывает реальные адреса и структуру микросервисов. Даже если злоумышленник получит доступ к BFF, он не увидит полную внутреннюю сеть.

Производительность клиента

  • Снижение числа запросов: клиент получает всё необходимое за один круговой путь (round-trip).
  • Уменьшение объёма передаваемых данных: только нужные поля, оптимизированные изображения, сжатие.
  • Более быстрый Time-to-Interactive: клиент может сразу отрисовать интерфейс, не дожидаясь нескольких ответов.
  • Кэширование на стороне BFF с использованием Redis или CDN для часто запрашиваемых данных.
  • Поддержка Server-Sent Events или WebSocket для real-time обновлений, если это необходимо клиенту.

Пошаговая инструкция по внедрению BFF

Шаг 1. Анализ клиентов и их требований

  • Определите все типы клиентских приложений (веб, мобильные, десктопные, IoT).
  • Для каждого клиента составьте список функций и данных, которые ему необходимы.
  • Выявите различия: какие данные нужны только мобильному приложению, какие — только вебу.
  • Оцените требования к производительности (время отклика, допустимое количество запросов).

Шаг 2. Проектирование BFF под каждый клиент

  • Решите, будете ли вы создавать отдельный BFF для каждого клиента или один BFF с разными точками входа (endpoints) для разных клиентов. Обычно предпочтительнее отдельные сервисы.
  • Для каждого BFF определите:
    Язык программирования и фреймворк (Node.js/Express, Python/FastAPI, Go, Java Spring и т.д.).
    Формат API (REST, GraphQL, gRPC, WebSocket).
    Структуру эндпоинтов и моделей данных.
    Протоколы взаимодействия с нижележащими сервисами (HTTP, gRPC, очереди).

Шаг 3. Настройка безопасности

  • Внедрите механизм аутентификации (JWT, OAuth2, OpenID Connect).
  • Настройте авторизацию (например, проверку ролей или прав) на уровне BFF.
  • Реализуйте валидацию входящих запросов (JSON Schema, параметры).
  • Установите лимиты запросов (rate limiting) для защиты от DDoS.
  • Настройте HTTPS и CORS в соответствии с потребностями клиентов.

Шаг 4. Реализация логики агрегации и адаптации

  • Разработайте код, который будет обращаться к внутренним сервисам (микросервисам, базам данных, внешним API) и собирать данные.
  • Реализуйте параллельные вызовы (async/await, futures) для уменьшения задержек.
  • Добавьте трансформацию данных: фильтрацию полей, изменение форматов, объединение ответов.
  • Реализуйте кэширование на уровне BFF (например, в памяти или Redis) для данных, которые редко меняются.

Шаг 5. Интеграция с клиентом

  • Предоставьте клиентским разработчикам документацию API (Swagger, GraphQL schema).
  • Настройте клиентские приложения на использование новых BFF-эндпоинтов.
  • При необходимости реализуйте fallback-механизмы на случай недоступности BFF.

Шаг 6. Тестирование

  • Проведите функциональное тестирование: проверьте, что клиент получает именно те данные, которые ожидает.
  • Нагрузочное тестирование: проверьте, как BFF справляется с пиковыми нагрузками от большого числа клиентов.
  • Тестирование безопасности: проверьте на уязвимости (SQL-инъекции, XSS, подделка запросов).
  • Тестирование производительности клиента: замерьте время загрузки, количество запросов, объём трафика.

Шаг 7. Мониторинг и логирование

  • Настройте сбор метрик (время ответа BFF, количество ошибок, RPS, загрузка CPU/памяти).
  • Организуйте централизованное логирование запросов и ошибок для отладки.
  • Установите алерты при превышении пороговых значений.

Шаг 8. Развёртывание и масштабирование

  • Разверните BFF в выбранной среде (контейнеры Kubernetes, виртуальные машины, serverless).
  • Обеспечьте горизонтальное масштабирование (добавление экземпляров BFF при росте нагрузки).
  • Настройте балансировку нагрузки и отказоустойчивость.

Шаг 9. Сопровождение и эволюция

  • Поддерживайте обратную совместимость API при изменениях.
  • При необходимости выпускайте новые версии BFF для поддержки новых версий клиентских приложений.
  • Анализируйте метрики и отзывы клиентов для дальнейшей оптимизации.

Страховка на собеседовании

Знание есть, но стресс мешает?
Бесплатное сообщество для прокачки карьеры в IT

Подпишись на https://t.me/IT_Interview_Partner_Bot

Подпишись на
https://t.me/LyakhovEugene