BFF расшифровывается как Backend for Frontend — «бэкенд для фронтенда». Это архитектурный паттерн, при котором между клиентским приложением (сайтом, мобильным приложением) и внутренними сервисами компании ставится отдельный промежуточный слой, заточенный под конкретный интерфейс. Вместо того чтобы мобильное приложение напрямую дёргало десяток микросервисов и самостоятельно склеивало ответы, оно делает один запрос к своему BFF — и получает готовые данные в нужном формате.
Термин стал популярным в середине 2010-х годов, когда компании начали массово переходить на микросервисную архитектуру. Выяснилось, что «один общий API на всех» плохо работает: веб-версии нужны одни данные, мобильному приложению — другие, а умным часам — вообще минимальный набор. BFF решает эту проблему, позволяя каждому типу клиента иметь собственный «персональный» бэкенд.
Зачем нужен BFF: какую проблему он решает
Представьте интернет-магазин с микросервисной архитектурой: отдельные сервисы для каталога, цен, остатков, отзывов, доставки и пользователей. Чтобы отрисовать карточку товара, мобильному приложению пришлось бы сделать шесть-семь запросов к разным сервисам, дождаться всех ответов и собрать их воедино. На медленном мобильном интернете это превращается в заметные задержки и лишний расход трафика.
BFF забирает эту работу на себя. Клиент отправляет один запрос, а промежуточный слой сам обращается к нужным микросервисам, агрегирует данные, отбрасывает лишнее и возвращает компактный ответ, готовый к отображению. Сетевая логика уходит с устройства пользователя в контролируемую серверную среду, где связность между сервисами быстрая и предсказуемая.
BFF убирает с клиента логику агрегации данных: один запрос вместо множества, ответ в формате «как нужно именно этому экрану».
Как устроена архитектура с BFF
Классическая схема выглядит так: клиенты (веб, iOS, Android) обращаются каждый к своему BFF, а те уже взаимодействуют с общими внутренними сервисами. Важно, что BFF не заменяет микросервисы — он лишь тонкий адаптер над ними.
- 📱 Мобильный BFF — отдаёт урезанные данные, оптимизированные под маленький экран и нестабильную сеть.
- 🖥️ Веб-BFF — может отдавать более «тяжёлые» ответы, включая данные для SEO и сложных интерфейсов.
- ⌚ BFF для ТВ или носимых устройств — минимальный набор полей, если такой клиент вообще есть.
- 🔧 Внутренние микросервисы — остаются общими и не знают ничего об особенностях клиентов.
Технологически BFF обычно пишут на том же стеке, что и фронтенд: часто это Node.js с Express или NestJS, реже — другие языки. Логика простая: команда фронтенда владеет своим BFF и меняет его под свои нужды, не ожидая правок в чужих сервисах.
Чем BFF отличается от API Gateway
Эти два понятия часто путают, потому что оба стоят «между клиентом и сервисами». Разница в назначении: API Gateway — это инфраструктурная точка входа (маршрутизация, авторизация, лимиты запросов, балансировка), а BFF — это слой бизнес-логики под конкретный интерфейс. Они не исключают друг друга и часто работают вместе.
| Критерий | API Gateway | BFF |
|---|---|---|
| Основная задача | Маршрутизация, безопасность, лимиты | Агрегация данных под конкретный UI |
| Количество | Обычно один на систему | Один на каждый тип клиента |
| Кто владеет | Инфраструктурная команда | Команда фронтенда |
| Знание о UI | Не знает о клиентах | Заточен под экраны и сценарии |
| Типовые инструменты | Kong, Nginx, облачные gateway | Node.js, GraphQL-серверы и др. |
На практике цепочка может выглядеть так: клиент → API Gateway → BFF → микросервисы. Gateway проверяет токен и направляет запрос, а BFF собирает данные для конкретного экрана.
Преимущества подхода
Главный плюс — скорость разработки интерфейсов. Фронтенд-команда получает данные именно в том виде, в каком они нужны компонентам, и не ждёт изменений в чужих сервисах. Заодно снижается нагрузка на клиентские устройства: меньше запросов, меньше трафика, меньше кода на стороне приложения.
- 🚀 Один запрос вместо множества — быстрее отрисовка экранов.
- 📉 Меньше трафика — критично для мобильных пользователей.
- 🔐 Чувствительные данные и ключи не покидают серверную зону.
- 🧩 Независимые релизы: веб и мобайл развиваются в своём темпе.
- 🛡️ Точка для кэширования, обрезки полей и скрытия внутренней структуры API.
BFF — удобное место для кэширования ответов микросервисов: повторные запросы клиентов обслуживаются мгновенно, а нагрузка на внутренние сервисы падает.
Недостатки и подводные камни
Паттерн не бесплатный. Каждый дополнительный BFF — это отдельный сервис, который нужно разворачивать, мониторить и поддерживать. При неаккуратном подходе логика начинает дублироваться между BFF для разных клиентов, и исправление одного бага приходится вносить в несколько мест.
⚠️ Внимание: частая ошибка — превращать BFF в «второй монолит», перенося в него бизнес-логику. BFF должен оставаться тонким слоем агрегации и трансформации данных; бизнес-правила принадлежат доменным сервисам.
Ещё один риск — рост числа команд и сервисов без реальной необходимости. Если у вас один клиент и простой бэкенд, отдельный BFF добавит сложности без ощутимой выгоды. Паттерн оправдан там, где клиентов несколько и их потребности заметно различаются.
Когда BFF нужен, а когда — лишний
Решение зависит от масштаба системы. Ориентируйтесь на конкретные признаки, а не на моду на архитектурные паттерны.
☑️ Признаки того, что вам пора внедрять BFF
И наоборот: если у вас один веб-клиент и простой CRUD-бэкенд, BFF, скорее всего, будет избыточен. Достаточно хорошо спроектированного API. BFF — это ответ на реальную боль мультиканальной системы, а не обязательный элемент любой архитектуры.
BFF и GraphQL
GraphQL часто используют как технологию для реализации BFF: клиент сам описывает, какие поля ему нужны, а сервер собирает их из разных источников. Это сочетает гибкость BFF с единой точкой входа. Однако GraphQL не равен BFF — паттерн можно реализовать и на обычном REST.
Типичная реализация на практике
Упрощённый пример эндпоинта BFF на Node.js, который собирает данные для экрана профиля из двух сервисов:
app.get('/api/profile', async (req, res) => {
const [user, orders] = await Promise.all([
fetch(`http://users-service/users/${req.userId}`).then(r => r.json()),
fetch(`http://orders-service/orders?userId=${req.userId}`).then(r => r.json())
]);
res.json({
name: user.name,
avatar: user.avatarUrl,
ordersCount: orders.length,
lastOrder: orders[0] ?? null
});
});
Обратите внимание: клиент получает только четыре поля, хотя внутренние сервисы могут возвращать десятки. Именно в этом суть — трансформация и обрезка данных под нужды экрана. В реальных проектах сюда добавляют обработку ошибок, таймауты, кэширование и авторизацию.
⚠️ Внимание: пример выше учебный. В продакшене обязательно добавляйте обработку недоступности сервисов (таймауты, fallback-ответы), иначе падение одного микросервиса уронит весь экран.
BFF — тонкий слой между клиентом и микросервисами, принадлежащий команде фронтенда. Он агрегирует, обрезает и отдаёт данные ровно в том виде, который нужен конкретному интерфейсу.
Часто задаваемые вопросы
Чем BFF отличается от обычного бэкенда?
Обычный бэкенд реализует бизнес-логику и работу с данными. BFF — это дополнительный прослойка над ним: он не хранит данные и не содержит бизнес-правил, а только собирает и форматирует ответы под нужды конкретного клиента.
Нужен ли отдельный BFF для каждого клиента?
Не обязательно. Если потребности веба и мобильного приложения совпадают, можно обойтись одним. Отдельные BFF заводят, когда различия в данных и сценариях становятся существенными и мешают развивать клиентов независимо.
Можно ли совмещать BFF и API Gateway?
Да, это распространённая схема: Gateway отвечает за маршрутизацию, авторизацию и лимиты, а BFF — за агрегацию данных под интерфейс. Они решают разные задачи и дополняют друг друга.
На каком языке писать BFF?
Чаще всего выбирают язык, близкий команде фронтенда, — обычно JavaScript/TypeScript на Node.js. Но ограничений нет: BFF можно писать на любом языке, главное — чтобы его поддерживала та команда, которая им владеет.
Подходит ли BFF для небольших проектов?
Как правило, нет. При одном клиенте и простом бэкенде дополнительный слой добавляет сложности без выгоды. Паттерн раскрывается в системах с несколькими клиентами и микросервисной архитектурой.