惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
P
Proofpoint News Feed
H
Help Net Security
V
Visual Studio Blog
阮一峰的网络日志
阮一峰的网络日志
C
Cisco Blogs
人人都是产品经理
人人都是产品经理
Know Your Adversary
Know Your Adversary
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Recorded Future
Recorded Future
I
Intezer
罗磊的独立博客
T
The Exploit Database - CXSecurity.com
Blog — PlanetScale
Blog — PlanetScale
Malwarebytes
Malwarebytes
Spread Privacy
Spread Privacy
T
Tor Project blog
V
Vulnerabilities – Threatpost
云风的 BLOG
云风的 BLOG
腾讯CDC
B
Blog RSS Feed
Stack Overflow Blog
Stack Overflow Blog
F
Future of Privacy Forum
MyScale Blog
MyScale Blog
Latest news
Latest news
IT之家
IT之家
MongoDB | Blog
MongoDB | Blog
The Hacker News
The Hacker News
S
Securelist
博客园 - 【当耐特】
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threat Research - Cisco Blogs
Jina AI
Jina AI
Cisco Talos Blog
Cisco Talos Blog
B
Blog
博客园 - 三生石上(FineUI控件)
Last Week in AI
Last Week in AI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
V
V2EX
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Cloudflare Blog
The GitHub Blog
The GitHub Blog
博客园 - 聂微东
F
Full Disclosure
C
CERT Recently Published Vulnerability Notes

Все публикации подряд на Хабре

«Продай мне этот космолёт» или история любви к симуляторам. От космосима X-Tension до ActorModel/DoD/ECS архитектуры. Ч3 Архитектурные компромиссы в разработке игр Ваш Kubernetes упал: найдёте root cause за 15 минут? Надо ли бороться с анизотропией эмбеддингов Злоумышленник публикует .bash_history: смотреть без регистрации и СМС Разбираемся в ML без воды: от базы до Attention. Часть 3 Как я сделал утилиту для автоматизации ручных тестов Почему факты не работают: шесть причин, по которым люди верят слухам Neko — собираем музыкальный гаджет в домашних условиях AI Evals: Почему без оценки качества ваш продукт стоит на месте Астрологическая схемотехника Безопасный Docker с torque Spring AI: феноменология цифрового сознания, или Как я перестал бояться и полюбил облачные модели [Перевод] Torque: релизы на автопилоте Сравниваем точность расчета копланарных линий передачи для СВЧ МИС: SimPCB Lite против Ansys HFSS Ошибка найма «рок‑звезды» — как один супер‑инженер разрушил команду за полгода Детекция чужого почерка в экзаменационных бланках без эталонного образца Как хедхантер превращает поиск работы в бег за «морковками» Баги, которые нас воспитали: инженерные истории с Go Loto Зачем ОС нужен Root-of-Trust и как KasperskyOS работает с разными реализациями А что, если управлять торговой платформой голосом? За 48 часов собрали голосового ассистента и проверили Ваша трансформация обречена на провал. Восемь причин, почему Иду в топ ниши строительных калькуляторов. Три месяца спустя HPSC: процессоры NASA, которые сделают космические аппараты по-настоящему умными Архитектура монорепозитория для параллельного исполнения торговых стратегий Чтобы не выглядело как пет-проект»: как я в одиночку сделал премиальный интерфейс кино-сервиса (с кодом) Вам продают ИИ. Покупать нужно не его Матрица компетенций джедая: как снизить Bus Factor на проекте Production начинается там, где заканчивается вайбкодинг От фич и каскадов к генеративной модели: как мы переосмыслили рекомендации с помощью ARGUS Отвечай, как топовый специалист: как службе поддержки решать настоящие, а не озвученные проблемы клиентов Новые IT-специалисты эпохи AI: как зарубежные и российские компании относятся к vibe-coders, low-coders и zerocoders Локальная система проверки персонала: как мы автоматизировали скрининг соискателей без передачи ПДн наружу Разрабатывали решение для автоматизации, а получили универсальный продукт «Мультиплексор для Лабораторных измерений» Подготовка и сдача экзамена PMP в мае 2026 года Время закрывать доски. Ваш SaaS таск-трекер — это просто слой лака над базой данных Как мы проектировали multi-agent feedback для обучения рисованию Что такое Gemma 4: обзор новой LLM от Google CyBOK. Глава 3. Законы и регуляторные нормы. Часть 8 LLM-инференс на фотонах? Препарируем передовые технологии, представленные в апреле Агенты выходят на работу (часть 3) Нехватка CUDA-памяти при обучении с GRPO: как перестать гадать и начать считать Окей, Lamoda, что надеть на вечеринку? Как обучить LLM навыкам ИИ-стилиста ArchiMate 4: Отказ от слоёв и унификация метамодели Дальнейшая судьба SFP-Master Игровой ПК или PlayStation 5: что выгоднее в 2026 году Flipper One — нам нужна ваша помощь Как мы построили корпоративную LLM-платформу: архитектура, грабли и выводы Устранить нельзя оставить — разбираем ситуацию с уязвимостями в российской виртуализации Bitrix и Laravel: веб-хуки, ERP и все-все-все (часть 5) Поиск секрета популярности лучших репозиториев GitHub за всё время существования платформы Сэкономили на облаке под 1С: ДО — заложили бюджет на штраф. Разбираем 152-ФЗ при работе с 1С Компьютерное зрение: что получается, когда у вас не идеальная лаборатория, а дождь, снег и подвижный манипулятор Параметризация в JUnit 5 и Allure Report Мне 15, и я собираю AI-стартап для недвижки: как я победил GPU, баги PyTorch и очередь в визовый центр Стратегия «Голубого океана»: как системный аналитик влияет на продукт Проектируем с нуля калькулятор на FPGA. Часть 3: Практические численные методы От видимости сети до кибербезопасности: главный миф о сетевой телеметрии, который мешает раскрыть потенциал NetFlow Как интегрировать ТСД с любой конфигурацией «1С: Предприятия»? Человеческие головы, сандалии и лягушки: стегоконтейнеры за тысячи лет до первого компьютера GigaIDE Pro для разработки на Django Как добиться непостоянного момента? Книга: «Kubernetes. Полное руководство по развертыванию и управлению Kubernetes в облачных и локальных средах. 2-е изд.» Почему IT-специалисты остаются: что работает на удержание в 2026 году Соединение деталей 3D-печатных изделий… Простое ли дело? Yamaha RGX121Z RM — современный суперстрат с японским вайбом второй половины 1980-х Как я написал плагин для WooCommerce под Yandex YCP или как купить в 1 клик из Алисы Креативное программирование: визуализация звука Сложно читать IT литературу на кривом русском? Есть решение — книжный ревью (рефакторинг) История о том, как человечество наняло очень странного сотрудника Как мы в отделе документации создали LLM агента для автоматизированного перевода с английского на другие языки Почему e-ink до сих пор не убил LCD, хотя должен был Как оплачивать нейросети и остальное недоступное в РФ в 2026: 9 способов с ценами и рисками, где можно влететь Решение проблем в управлении: почему мидл-менеджеры справляются с кризисами эффективнее топов Сколько телефонов и планшетов продали партнёры: единое хранилище данных для бренда электроники Google Fellow, студент Нанкина и создатель TikTok: кто сделал Seedream и Seedance. Досье SpeShu.AI В прорывном эксперименте из первых в мире полностью искусственных яиц вылупились птенцы Разворачиваем облачный ТОиР на заводе за две недели Vivaldi 8.0 — Унифицированная свобода выбора Как мы с нуля реализовали двустороннее доверие «лес–лес» с Microsoft Active Directory Хакер спас мир и сел в тюрьму: Невероятная история Маркуса Хатчинса и червя WannaCry Построение корпоративной архитектуры в ИТ-проектах, используя методологию TOGAF Пайплайн не должен хранить секрет: безопасное хранение и доставка секретов для CI/CD с Deckhouse Code и Stronghold ОГЭ информатика. 16 задание на Python Asus, MSI и Gigabyte урезают производство материнских плат. Что происходит на рынке Claudex: как я подружил Claude Code с ChatGPT/Codex OAuth без OpenAI API key Как измерить скорость интернета? Почему выгорают не слабые, а ваши Версионирование таблиц репозитория метаданных Sigla Vision Графическая утилита PostgreSQL mini Profiler (в помощь экспертам по технологическим вопросам 1С и не только им) Шахматные программы IV. Термины и методы Почему Я.Директ не приводит премиальных клиентов и что с этим делать – продали элитных туров на 600 млн Реестр отечественного ПО: как бизнесу выбрать решение среди 30 000 записей и не ошибиться Глаза не видят, а код пишется: как я настраиваю и программирую 100+ модулей в умном доме Архитектура AI-сервисов: почему монолит убивает latency и GPU Процессы: чего до сих пор не хватало обычным BPM (Часть 2) Книжный салон — дополнительные книги от издательства «БХВ». Предзаказ Как продакту довести фичу до прода без PMBOK и PRINCE2 Оргмодель, процессы и агенты (Часть 1) Probe-сеть из 10 регионов: что я не учёл про AS-разнесённость
Паттерн Backend for Frontend (BFF) в разработке современных приложений
cvartan (Син · 2026-05-22 · via Все публикации подряд на Хабре

Привет, Хабр! Я — Константин Вартаньянц, системный аналитик-эксперт в «Синимекс». Мне приходится проектировать системы на микросервисах, и я нередко  сталкиваюсь с одной и той же историей: как построить бэкэнд для сложных приложений со множеством фронтендов.

В поисках решения я столкнулся с подходом Backend for Frontend, использовал его для проектирования и реализации нескольких систем и теперь хочу поделиться своим опытом.

Проблема: почему нельзя просто взять и написать один бэкенд для всех

Начну с главного. Какая главная задача у бэкенда, где крутится вся бизнес-логика? Правильно, обслуживать бизнес-процессы. Для него пользователь — это просто управляющий элемент: прилетели данные и команды, он их обработал, вернул результат и процесс пошел дальше. Ему глубоко всё равно, какой кнопкой, формой или голосом эти данные ввели. А вот у фронтенда работа другая — сделать так, чтобы пользователю было удобно, понятно и приятно. Это мир UX-гипотез, A/B-тестов и постоянной борьбы за лучший интерфейс. И для всех этих «рюшечек» и экспериментов ему нужны данные, которые в строгой бизнес-логике обычно не предусмотрены.

Когда мы пытаемся в одном бэкенде совместить и строгую бизнес-логику, и все эти «рюшечки» для фронта — получается монстр Франкенштейна. В коде смешивается логика предметной области (например, доменная модель из DDD, то есть модель, описывающая ключевые бизнес-сущности и правила их взаимодействия) и логика подготовки данных для конкретной формы в интерфейсе.

В итоге получается, что стабильная по своей природе бизнес-логика начинает дёргаться от каждой «косметической» правки в интерфейсе. Решили на фронте добавить пару колонок в таблице — и вот уже летит задача на доработку бэка. Это не только усложняет код, но и кратно повышает риск регресса (ситуации, когда после обновления ломается то, что раньше работало). 

Добавьте к этому, что у нас часто не один, а несколько фронтендов: веб-сайт для клиентов, админка для сотрудников, мобильное приложение. У каждого свои пользователи, свои сценарии и свои «хотелки». Чтобы угодить всем, бэкенд-разработчикам приходится плодить десятки почти одинаковых методов, которые раздувают кодовую базу и усложняют тестирование.

И далее, самая больная тема — безопасность. Если бэкенд отдаёт «сырые» данные, а фронтенд сам решает, что показать пользователю, а что нет, — это огромная дыра в безопасности. Любой студент, открывший инструменты разработчика в браузере, увидит всё, что от него пытались скрыть. 

Очевидно, что вся фильтрация конфиденциальных данных должна происходить на сервере. Но это ещё не всё. Чтобы правильно нарисовать интерфейс — показать нужные кнопки, сделать поля доступными или неактивными — фронтенду часто нужны данные о правах пользователя. Отдавать всю модель прав на клиента — либо небезопасно, либо технически невозможно. Значит, бэкенд должен сам решать, что можно, а что нельзя. И мы снова возвращаемся к проблеме: либо мы плодим методы под каждую роль, либо строим один гигантский универсальный метод, поддерживать который — боль.

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

Что такое BFF и как он работает

Место BFF в архитектуре системы

Место BFF в архитектуре системы

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

Как это работает? Основные бизнес-сервисы очищаются от всего, что связано с «красотой»: в них остаются только чистые методы, реализующие бизнес-логику. Всю грязную работу берёт на себя BFF: он стучится в разные микросервисы, собирает от них данные, форматирует, фильтрует и отдаёт фронтенду в идеально готовом для употребления виде. В результате команда фронтенда может менять интерфейс как угодно — пока это не затрагивает суть бизнес-процесса, бэкенд-разработчики могут спать спокойно.

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

Плюсы и минусы подхода BFF

Перечислим плюсы, которые дает внедрение паттерна Backend for Frontend. 

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

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

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

  • Разные темпы разработки. У бизнес-логики и логики взаимодействия с пользователем совершенно разные жизненные циклы. Бизнес-процессы меняются редко и основательно. Интерфейс — это динамичная среда, где постоянно проверяются гипотезы и меняется дизайн. Выделение BFF-сервиса позволяет разорвать эту зависимость. Команда фронтенда получает свой собственный «бэкенд», который может развивать в нужном ей темпе, не отвлекая команду, ответственную за ядро системы. Конфликты между командами из-за разной скорости работы сходят на нет.

  • Лёгкое подключение новых клиентов. Появилось у нас мобильное приложение или, скажем, терминал для самообслуживания? Не проблема. Мы не трогаем основные сервисы, а просто пишем для нового клиента свой BFF. Это также упрощает поддержку старых версий приложений: можно менять API для новой версии, сохраняя совместимость для старой на уровне BFF.

Но, как известно, за всё хорошее надо платить. Внедрение дополнительного слоя в архитектуру — это не бесплатно.

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

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

  • Рост сложности разработки и дублирование кода. Логика теперь «размазана» по нескольким сервисам, что усложняет разработку и тестирование. А если у нас веб-сайт и мобильное приложение с похожими экранами, то, скорее всего, придётся написать два почти одинаковых BFF, а значит, и поддерживать дублирующийся код.

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

Когда без BFF не обойтись: критерии и стратегия внедрения

Разберёмся, какие флажки должны зажечься на дашборде проекта, чтобы всерьёз задуматься о внедрении BFF.

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

  2. Жёсткие требования ИБ. Если вам нужно жёстко контролировать, какие данные уходят на клиент, а впихивать эту логику в основные сервисы — значит превращать их в клубок спагетти, BFF — ваш выбор. Особенно это спасает при работе с унаследованными системами (legacy), которые трогать страшно и дорого. Проще поставить рядом с таким «чёрным ящиком» BFF-конвертер, который будет забирать из него всё, а наружу отдавать только разрешённое.

  3. Данные разбросаны по разным сервисам. Когда для отрисовки одного экрана фронтенду нужно сходить в пять-десять разных микросервисов, это явный перебор. Перекладывать эту агрегацию на плечи клиента — плохая идея: приложение станет медленным и прожорливым. Создавать отдельный сервис-агрегатор? Так это и есть одна из ключевых функций BFF. Если без агрегации никак, значит, вам нужен BFF.

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

Хорошо, допустим, мы взвесили все «за» и «против» и решили, что BFF нам необходим. 

Как его внедрять? 

Если проект только начинается, всё просто — слой BFF можно сразу заложить в архитектуру. 

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

Начать можно с так называемого смешанного режима. Простые запросы пусть продолжают ходить напрямую в основные сервисы (через API Gateway, то есть единую точку входа для всех запросов). А вот для новых, сложных задач мы сразу начинаем использовать BFF.

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

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

Такой подход позволяет растянуть переходный период, внедрять изменения небольшими, контролируемыми порциями и не взрывать инфраструктуру и процессы разработки одним махом.

Проектирование BFF: от данных к экранам

Раз уж мы переносим логику с фронта на бэк, стоит упомянуть подход Screen as a Service. Суть его в том, чтобы проектировать API не вокруг абстрактных сущностей («пользователи», «заказы»), а вокруг конкретных экранов в интерфейсе. Мы думаем не «какие данные у нас есть», а «какие данные нужны пользователю на этом конкретном экране».

API для BFF идеально ложится на эту концепцию. Мы проектируем его «от экрана». Фронтенд говорит: «Дай мне всё для экрана „Карточка товара“», — и BFF возвращает один-единственный JSON, в котором уже всё собрано, отформатировано и готово к отрисовке. Внутри себя BFF сам сходит во все нужные сервисы, соберёт данные и применит все правила.

Чем это может помочь?

Во-первых, радикально облегчается спецификация API. Вместо описания десятков мелких методов для получения разрозненных данных, я описываю ресурсы-экраны. Техническое задание строится вокруг пользовательских сценариев: «Для экрана „Список заказов“ нужны такие-то поля, сгруппированные по статусу». И в результате появляется только один метод API, готовящий данные для этого экрана.

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

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

Истории из жизни: как мы внедряли BFF

В дополнение к сказанному хотел привести примеры решения пары практических задач, которые решались с использованием данного паттерна.

История первая: собираем «зоопарк» в одном месте. У нас была система, где исторически каждый тип заявок (кредитные, сервисные и т.д.) жил в своём микросервисе. У каждого был свой формат данных и свой интерфейс. Пока пользователи работали с ними в разных разделах портала, всё было терпимо. Но со временем этот «зоопарк» разросся до неприличных размеров.

Появились новые требования: 

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

  2. Так как в списке будут все типы заявок, то необходимо при отображении или к обращении к заявке в списке учитывать привилегии пользователя для типа заявки.

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

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

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

  2. не хотелось бы опять в рамках одного сервиса смешивать бизнес-логику и логику работы с фронтом (а в перспективе было, что для каждого нового типа заявки нужно было бы дорабатывать API).

Вариант с агрегацией данных на фронтенде отмёлся сразу из-за высокой нагрузки на клиентское устройство.

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

В случае получения общего списка заявок (с общим фильтром и сортировкой) фронтенд отправлял один-единственный запрос с фильтрами и параметрами страницы, а дальше начиналась обработка на стороне BFF.

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

Далее, поскольку наш BFF был «приклеен» к конкретному экземпляру фронтенд-приложения (через sticky session на API Gateway, механизм, который направляет все запросы одного пользователя на один и тот же сервер), он мог позволить себе хранить состояние между запросами. При переходе на следующую страницу списка сервис уже знал, что мы запрашивали раньше, и подгружал только недостающие данные, используя кэш.

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

И наконец, на последнем шаге, на основе привилегий текущего пользователя и данных каждой заявки, BFF вычислял доступные для неё действия: «редактировать», «просмотреть», «согласовать» и так далее. Эти флаги добавлялись прямо в объект с данными заявки. Фронтенду оставалось лишь отрисовать полученный список и показать нужные кнопки в каждой строке — никакой логики разграничения доступа на клиенте не осталось.

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

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

История вторая: выносим всю логику авторизации из фронтенда. Раз уж у нас появился такой мощный инструмент, как BFF, мы решили пойти дальше и максимально «облегчить» фронтенд, вынеся из него всю логику, связанную с правами доступа.

Сложность была в том, что в компании жило несколько систем аутентификации и авторизации. Вдобавок к этому, у нас была собственная, довольно развесистая модель прав, которая использовала не только RBAC-подход (на основе ролей), но и ABAC (на основе атрибутов самих данных). Разбирать весь этот зоопарк на стороне фронтенда было бы трудоёмко и небезопасно.

Поэтому всю функцию определения видимости элементов интерфейса и, по сути, полной настройки GUI по ролям мы вынесли в слой BFF.

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

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

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

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

Вот, собственно, и всё. Как видите, BFF — это не просто паттерн, это философия. Философия разделения ответственности, которая позволяет бизнес-логике оставаться чистой и стабильной, а интерфейсам — развиваться и экспериментировать. Это способ подружить два мира, живущих в разном ритме.

Конечно, это не пуля из серебра, и за удобство приходится платить сложностью. Но в больших системах с кучей клиентов и жёсткими требованиями к безопасности игра, на мой взгляд, определённо стоит свеч. А как вы решаете подобные задачи? Встречали «монстров Франкенштейна» в своих проектах? Делитесь опытом в комментариях, будет интересно обсудить!