javascript

Когда нужен BFF и стоит ли смешивать его с API gateway

  • понедельник, 2 марта 2026 г. в 00:00:04
https://habr.com/ru/articles/1005128/

Всем привет, уважаемые читатели! В архитектуре проектов мы можем наблюдать применение паттерна BFF (Backend for frontend). При этом BFF может быть в архитектуре, где есть взаимодействие с клиентскими приложениями: веб, мобильное, смарт-устройства и т.д, но может быть всего-навсего один служебный фронтенд, доступ к которому возможен во внутрикорпоративном сегменте, например, банковская система, hr, логистика. Кажется, что при наличии одного фронтенда введение BFF избыточно.

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

Но что, если фронтенд один и вдруг нуждается в данных из разных API системы, чтобы нормально функционировать? При этом запросы могут быть сложными: каждый требует особых параметров и возвращает много лишней информации. А если у вас несколько клиентских приложений и так же нужно подтягивать данные из разных API?

Знакомимся с паттерном BFF

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

В SoundCloud приняли решение разделить API на отдельные сервисы для взаимодействия с фронтендами. Каждый такой BFF-был выделен в отдельную зону ответственности – это позволило быстро реагировать под нужды и специфику каждого клиентского приложения. Подробнее ознакомиться с истоками и паттернами BFF можно тут: https://samnewman.io/patterns/architectural/bff/

Выделение BFF сервисов для взаимодействия с клиентскими приложениями в архитектуре SoundCloud
Выделение BFF сервисов для взаимодействия с клиентскими приложениями в архитектуре SoundCloud

Основной плюс решения SoundCloud заключается в том, что теперь контракты API конкретно подстраиваются под каждый тип клиента и не зацепляют друг друга, побочно выделение взаимодействия с клиентами в отдельный контекст позволило распилить монолитную архитектуру проекта – паттерн «Душитель». С другой стороны, наверняка SoundCloud под каждый BFF сервис выделил ресурсы для поддержания каждой из зон ответственности – это дополнительные расходы.

Cвязь BFF паттерна и API Gateway

Может возникнуть вопрос, а зачем нам нужен BFF, когда можно отделаться API Gateway и объединить все запросы в одном шлюзе. Такой вопрос вполне может возникнуть там, где есть «один фронтенд» и нет разных клиентских приложений. Как тут поступить?

Прежде чем ответить на этот вопрос – давайте определим концептуальные варианты использования BFF и API Gateway.

API Gateway

API Gateway — это точка входа всей системы, пример основных функциональностей:

  • Маршрутизация: Направить запрос от клиента к нужному микросервису .

  • Termination SSL: Расшифровать HTTPS-трафик, чтобы внутри сети данные шли без лишних сетевых издержек.

  • Rate Limiting: Ограничить количество запросов от одного IP или клиента, чтобы защитить бэкенд от DDoS и перегрузок.

  • Аутентификация: Проверить, что токен в принципе валиден (не просрочен, подпись верна).

  • Балансировка нагрузки: Распределить запросы между экземплярами микросервисов.

Важно: API Gateway не знает бизнес-логику. Ему всё равно, что внутри запроса — он просто проксирует трафик.

BFF

BFF — это уже про бизнес-логику конкретного интерфейса:

  • Агрегация данных: Собрать в одном ответе данные из 3-5 разных микросервисов (пользователь + корзина + заказы).

  • Трансформация ответа: Обрезать поля, переименовать их, преобразовать форматы (например, unix timestamp в человеческую дату).

  • Пагинация и фильтрация: Подготовить данные именно так, как хочет конкретный клиент (10 элементов для мобилки, 50 для веба).

  • Клиент-специфичная логика: Добавить поля, которые нужны только этому интерфейсу (например, флаг "показывать анимацию").

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

API gateway и BFF работают вместе и каждый компонент реализует свою концептуальную бизнес-логику
API gateway и BFF работают вместе и каждый компонент реализует свою концептуальную бизнес-логику

Стоит ли смешивать BFF и API gateway?

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

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

Когда стоит использовать BFF?

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

Критерий

BFF нужен

BFF не нужен

Архитектура

Много микросервисов, данные для одной страницы нужно собирать из 3+ источников

Монолит или один сервис, который отдаёт уже готовые агрегированные данные

Формат данных от бэкенда

Бэкенд отдаёт "сырые" данные (Protobuf, XML, странные структуры) или данные из legacy-систем

Бэкенд отдаёт JSON, готовый для UI без дополнительной обработки

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

Бэкенд нельзя открывать наружу, нужна прослойка для изоляции

Можно открыть бэкенд напрямую с авторизацией

Команды и оргструктура

Разные команды отвечают за разные клиенты

Одна команда делает и фронт, и бэк, релизы синхронизированы

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

Критично минимизировать количество запросов с клиента

Клиент может делать несколько запросов без потери качества

На чьей стороне должен быть BFF?

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

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

Итог

BFF нужен, когда:

  • Есть разнородные клиенты с разными потребностями

  • Есть сложность на стороне бэкенда (микросервисы, legacy)

  • Есть потребность в независимости команд

BFF не нужен, когда:

  • Всё просто (один клиент, один бэкенд, одна команда)

  • Бэкенд уже отдаёт данные в том виде, который нужен UI

  • Дополнительный слой только добавит сложности без выгоды

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