Backend for Frontend (BFF): ускоряем мобильные и веб-приложения

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

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Backend for Frontend (BFF): ускоряем мобильные и веб-приложения
Сложный
~2-4 недели
Часто задаваемые вопросы

Мобильное приложение делает 5–10 последовательных HTTP-запросов для загрузки одной страницы. На мобильной сети каждый round trip добавляет 200–500 мс — суммарно до 2–3 секунд. Типичный сценарий: /users/{id}, /orders?userId={id}&limit=3, /notifications/unread, /recommendations?userId={id}, /loyalty/points/{id}. Клиент должен сам дождаться всех ответов и выполнить трансформацию. Это не только медленно, но и потребляет лишний трафик: загрузка ненужных полей (например, полный адрес при просмотре корзины) увеличивает объём передаваемых данных на 30–50%. Экономия на трафике и инфраструктуре может достигать 40% после внедрения BFF. Мы предлагаем внедрить промежуточный слой Backend for Frontend (BFF).

BFF — это отдельный бэкенд-сервис, создаваемый под конкретный тип клиента (веб, мобильное приложение, Smart TV). Он принимает один запрос от клиента, параллельно обращается к необходимым микросервисам, агрегирует данные, отсекает лишнее и возвращает результат в формате, оптимальном для данного клиента. Концепция подробно описана в статье Мартина Фаулера Backend for frontend.

Какие проблемы решает BFF?

  • N+1 запрос и задержки. Типичная картина: 5–10 последовательных вызовов для одной страницы. BFF сокращает это до одного вызова, выполняя параллельные запросы к сервисам. Экономия времени — до 80% round trips.
  • Избыточные данные. Микросервис отдаёт поля, не нужные клиенту (например, адрес при просмотре корзины). BFF отсекает лишнее, снижая объём передаваемых данных на 30–50%.
  • Сложная аутентификация. JWT, refresh token, httpOnly cookie — BFF управляет сессиями централизованно, не раскрывая доступ к сервисам из клиента.
  • Частичные сбои. Если один сервис недоступен, BFF может вернуть частичный ответ (null для упавшего фрагмента) вместо 500 ошибки.
  • Кеширование общих данных. Размещение BFF между клиентом и сервисами позволяет кешировать агрегированные ответы (например, рекомендации), снижая нагрузку на микросервисы на 40%.

Как мы реализуем BFF: стек и примеры

На практике BFF удобно строить на Node.js с Express или Apollo Server (GraphQL). В проектах мы используем Node.js, TypeScript, Express или Apollo Server, Redis для кеширования (ioredis), axios для HTTP-запросов.

Пример для мобильного приложения

Требуется один эндпоинт /mobile/dashboard, возвращающий профиль, последние заказы, уведомления и баллы лояльности.

// mobile-bff/routes/dashboard.ts
router.get('/mobile/dashboard', authenticate, async (req, res) => {
  const userId = req.user.id;
  const [userResult, ordersResult, notificationsResult, loyaltyResult] = await Promise.allSettled([
    userService.get(`/users/${userId}`),
    orderService.get(`/orders?customerId=${userId}&limit=3&fields=id,status,total,createdAt`),
    notificationService.get(`/notifications/${userId}/unread-count`),
    loyaltyService.get(`/loyalty/${userId}/summary`)
  ]);
  const response = {
    user: userResult.status === 'fulfilled' ? {
      id: userResult.value.data.id,
      name: userResult.value.data.displayName,
      avatar: userResult.value.data.avatarUrl
    } : null,
    recentOrders: ordersResult.status === 'fulfilled' ? ordersResult.value.data.items.map(transformOrderForMobile) : [],
    unreadCount: notificationsResult.status === 'fulfilled' ? notificationsResult.value.data.count : 0,
    loyalty: loyaltyResult.status === 'fulfilled' ? {
      points: loyaltyResult.value.data.balance,
      tier: loyaltyResult.value.data.tier
    } : null
  };
  res.json(response);
});

Пример для веб-клиента

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

// web-bff/routes/dashboard.ts
router.get('/web/dashboard', authenticate, async (req, res) => {
  const userId = req.user.id;
  const [user, orders, stats, notifications] = await Promise.allSettled([
    userService.get(`/users/${userId}`),
    orderService.get(`/orders?customerId=${userId}&limit=10`),
    analyticsService.get(`/analytics/user/${userId}/stats`),
    notificationService.get(`/notifications/${userId}?limit=5&unread=true`)
  ]);
  res.json({
    user: user.status === 'fulfilled' ? user.value.data : null,
    orders: orders.status === 'fulfilled' ? orders.value.data : { items: [], total: 0 },
    analytics: stats.status === 'fulfilled' ? stats.value.data : null,
    notifications: notifications.status === 'fulfilled' ? notifications.value.data : []
  });
});
Развернуть пример для GraphQL BFF
// web-bff/graphql/schema.ts
const typeDefs = gql`
  type Query {
    dashboard: Dashboard!
    order(id: ID!): Order
  }

  type Dashboard {
    user: User!
    recentOrders: [Order!]!
    stats: UserStats!
  }
`;

const resolvers = {
  Query: {
    dashboard: async (_, __, { userId }) => {
      const [user, orders, stats] = await Promise.all([
        userService.getUser(userId),
        orderService.getRecentOrders(userId),
        analyticsService.getUserStats(userId)
      ]);
      return { user, recentOrders: orders, stats };
    }
  }
};

Как реализовать авторизацию и кеширование в BFF?

BFF — естественное место для централизованной авторизации и кеширования. JWT-токен проверяется на уровне BFF, refresh token хранится в httpOnly cookie (для веб-клиента), а кеш в Redis ускоряет ответы для редко меняющихся данных.

// authorization middleware
router.post('/auth/refresh', async (req, res) => {
  const refreshToken = req.cookies.refresh_token;
  if (!refreshToken) return res.status(401).json({ error: 'No token' });
  const tokens = await authService.refreshTokens(refreshToken);
  res.cookie('refresh_token', tokens.refreshToken, {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 30 * 24 * 60 * 60 * 1000
  });
  res.json({ accessToken: tokens.accessToken });
});

// caching with Redis
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL);
async function getCachedOrFetch<T>(key: string, ttl: number, fetcher: () => Promise<T>): Promise<T> {
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);
  const data = await fetcher();
  await redis.setex(key, ttl, JSON.stringify(data));
  return data;
}

Выбор между GraphQL и REST для BFF

Если клиент — React-приложение с Apollo Client, BFF может экспортировать GraphQL-схему. Это даёт клиенту возможность запрашивать ровно те поля, которые нужны, без дублирования эндпоинтов. GraphQL BFF особенно удобен, когда требования к данным часто меняются: клиент сам контролирует выборку. Однако для простых мобильных приложений с фиксированными экранами REST BFF часто оказывается эффективнее из-за меньшей сложности.

Что входит в работу

  • Аудит текущей архитектуры и выявление частых round trips.
  • Проектирование BFF-слоя для каждого клиента (REST или GraphQL).
  • Разработка API с агрегацией данных и трансформацией.
  • Внедрение авторизации (JWT, session-based).
  • Кеширование с Redis или in-memory.
  • Обработка ошибок и partial failures (Promise.allSettled).
  • Документация (OpenAPI или GraphQL SDL).
  • Тестирование и нагрузочное тестирование.
  • Деплой (Docker, Nginx, Vercel, AWS Lambda).

Сроки реализации

Тип BFF Срок
REST BFF для 1 клиента (3–5 эндпоинтов) 1–2 недели
GraphQL BFF + авторизация + кеширование 2–3 недели
BFF для 2–3 клиентов с общей библиотекой 3–4 недели

Процесс работы

  1. Аналитика — изучаем схему запросов и выделяем узкие места.
  2. Проектирование — определяем набор агрегируемых эндпоинтов и стек.
  3. Реализация — пишем BFF-слой, кеширование, авторизацию.
  4. Тестирование — модульные, интеграционные, performance-тесты.
  5. Деплой — развёртывание и настройка мониторинга.

Типичные ошибки при внедрении BFF

  • Дублирование логики — каждый BFF дублирует трансформации. Решение: вынести общие функции в shared library.
  • Монолитный BFF — один BFF для всех клиентов приводит к тем же проблемам, что и единый API. Каждый клиент — отдельный BFF.
  • Игнорирование partial failures — если один сервис не отвечает, BFF не должен падать. Используйте Promise.allSettled.
  • Отсутствие кеширования — без кеша каждый запрос долетает до сервисов, увеличивая нагрузку и время ответа.

Почему BFF превосходит единый API?

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

Наш опыт

Мы внедрили BFF для крупного e-commerce проекта. Результаты:

Параметр Без BFF С BFF
Количество запросов на экран 7 1
Время загрузки 3.2 с 0.8 с
Трафик на экран 150 КБ 80 КБ
Нагрузка на сервисы 100% ~60%

Опыт наших инженеров — 8+ лет в микросервисной архитектуре. Закажите разработку BFF под ключ и получите гарантию на время ответа и отказоустойчивость. Свяжитесь с нами для консультации — оценим ваш проект за 1–2 дня. Закажите разработку BFF и получите оптимизацию под ваш клиент.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060