Next.js как BFF: Route Handlers, Server Actions и слой данных
← Назад к статьям

июль 2026 г.

Next.js как BFF: Route Handlers, Server Actions и слой данных

Четвёртая статья цикла: где заканчивается frontend и начинается backend в Next.js, как проектировать BFF, когда использовать Route Handlers, Server Actions, внешний API и прямой доступ к базе.

Next.js давно перестал быть только способом рендерить React-страницы. В App Router он умеет принимать HTTP-запросы, выполнять серверные функции, читать cookies, работать с headers и собирать данные из разных источников. Из-за этого у команды быстро появляется вопрос: Next.js — это frontend, backend или BFF?

Короткий ответ

В продуктовой архитектуре Next.js чаще всего стоит рассматривать как Backend for Frontend. Он адаптирует данные под интерфейс, держит серверный рендеринг, управляет кешем и скрывает детали внешних API. Но тяжёлую доменную логику, транзакции, очереди и интеграции уровня core-системы лучше выносить в отдельный backend.

Что такое BFF в контексте Next.js

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

Route Handlers

Route Handlers в папке app/api подходят для HTTP endpoints: webhook, healthcheck, callback авторизации, прокси к внешнему сервису, загрузка файла, простая операция формы. Это хороший выбор, когда вам нужен явный URL и стандартная HTTP-семантика.

ts
// app/api/health/route.ts
export async function GET() {
  return Response.json({ status: 'ok' });
}

Server Actions

Server Actions удобны для мутаций, которые вызываются из компонентов: отправить форму, обновить профиль, создать комментарий, применить фильтр. Они уменьшают количество ручного API-кода, но требуют дисциплины: валидация, проверка прав и обработка ошибок всё равно должны быть на сервере.

ts
'use server';

export async function updateProfile(formData: FormData) {
  const user = await requireUser();
  const input = parseProfileForm(formData);
  await profileService.update(user.id, input);
  revalidatePath('/account');
}

Слой данных

Не стоит писать fetch прямо в каждом page.tsx. Лучше выделить функции уровня lib или features: getArticle, getCurrentUser, getDashboardStats. Так проще тестировать, менять источник данных и централизованно настраивать retry, timeout, кеш и ошибки.

ts
export async function getArticle(slug: string) {
  const response = await fetch(`${CMS_URL}/api/articles?slug=${slug}`, {
    next: { revalidate: 600 },
  });

  if (!response.ok) throw new Error('Article fetch failed');
  return response.json();
}

Когда нужен отдельный backend

  • Есть сложная доменная логика и транзакции.
  • Одни и те же API нужны web, mobile, partners и internal tools.
  • Нужны очереди, долгие задачи, фоновые воркеры и event-driven архитектура.
  • Есть строгие требования к безопасности, аудиту или изоляции сервисов.

Типовая архитектура

Для растущего проекта разумная схема выглядит так: браузер обращается к Next.js, Next.js рендерит страницы и работает как BFF, а доменные сервисы отвечают за бизнес-логику. CMS, auth provider, payments, search и analytics подключаются через отдельные адаптеры.

SEO и semantic retrieval

Для SEO важно, чтобы данные страницы были доступны в первичном HTML, а не появлялись только после клиентского запроса. Для AI-поиска и multi-vector retrieval важна ясная терминология: BFF, Route Handlers, Server Actions, data layer, backend boundary. Если статья последовательно объясняет связи между этими сущностями, её проще сопоставить с длинными инженерными запросами.

FAQ

Можно ли писать backend полностью на Next.js?

Можно для небольших и средних продуктов, особенно если логика проста. Для высоконагруженных систем лучше отделять core backend от слоя рендера и BFF.

Что выбрать: Route Handler или Server Action?

Если нужен публичный или интеграционный HTTP endpoint, выбирайте Route Handler. Если действие вызывается из формы или компонента внутри приложения, часто удобнее Server Action.

Итог

Next.js силён как слой, который соединяет UI, серверный рендеринг и данные. Но чем выше нагрузка и сложнее домен, тем важнее явно провести границу: Next.js отвечает за web experience, а отдельные сервисы — за долговечную бизнес-логику.

Практический цикл статей о Next.js: от первого приложения и архитектуры проекта до рендеринга, кеширования, авторизации, наблюдаемости, деплоя и проектирования высоконагруженного веб-сервиса.

  1. 1.Next.js: Полный гайд по фреймворку для React
  2. 2.Next.js: настройка проекта, маршруты и первая архитектура
  3. 3.Next.js рендеринг и кеширование: SSR, SSG, ISR и Server Components
  4. 4.Next.js как BFF: Route Handlers, Server Actions и слой данных← вы здесь
  5. 5.Авторизация и безопасность в Next.js: cookies, Middleware, CSRF и rate limiting
  6. 6.Производительность Next.js: Core Web Vitals, изображения, streaming и размер бандла
  7. 7.Next.js в production: деплой, CDN, observability и высокая нагрузка

# Где это применено на практике

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

Контакт

Напишите мне

Открыт к интересным проектам и предложениям о сотрудничестве

Или напрямую:

i@paulislava.space