JavaRush /Курсы /Модуль 4: Node.js, Next.js и Angular /Связь между Server Actions и API Routes

Связь между Server Actions и API Routes

Модуль 4: Node.js, Next.js и Angular
12 уровень , 7 лекция
Открыта

1. Server Actions и API Routes в Next.js 15

Next.js 15 — это не просто ещё одна версия популярного фреймворка, а целый новый взгляд на архитектуру современных React-приложений. В нём появилось сразу два способа работы с серверным кодом:

  • API Routes (Route Handlers) — классический способ организации серверных эндпоинтов. Вы пишете файлы route.ts (или .js) в папке app/api, и эти файлы становятся доступны по HTTP, как обычные REST API.
  • Server Actions — новый подход, позволяющий вызывать серверные функции напрямую из компонентов, без явных fetch-запросов, через <form action={serverAction}> или программно.

Казалось бы, зачем нам две разные системы? Всё дело в удобстве и сценариях использования.

Как работают API Routes (Route Handlers)

Сначала немного повторения из прошлых лекций.

API Routes (или Route Handlers) — это обработчики HTTP-запросов, которые живут в папке app/api. Каждый такой файл экспортирует асинхронную функцию для одного или нескольких HTTP-методов:

// app/api/todos/route.ts
import { NextResponse } from 'next/server';

export async function GET(request) {
  // Получить список задач
  return NextResponse.json([{ id: 1, title: 'Учить Next.js' }]);
}

export async function POST(request) {
  // Добавить новую задачу
  const data = await request.json();
  // ...логика сохранения
  return NextResponse.json({ success: true }, { status: 201 });
}

Кратко:

  • Можно обрабатывать любые HTTP-методы.
  • Работает как обычный API: fetch-запросы, сторонние клиенты, Postman — всё доступно.
  • Подходит для интеграции с внешними сервисами, мобильными приложениями, сторонними фронтендами.

2. Как работают Server Actions

Server Actions — это новый способ вызывать серверный код напрямую из React-компонентов, не задумываясь о ручных fetch-запросах. Вы определяете функцию с директивой "use server", и Next.js сам организует передачу данных между клиентом и сервером.


// app/actions/todoActions.ts
'use server';

export async function addTodo(formData) {
  const title = formData.get('title');
  // ...логика добавления задачи
}

В компоненте:


import { addTodo } from '../actions/todoActions';

export default function TodoForm() {
  return (
    <form action={addTodo}>
      <input type="text" name="title" />
      <button type="submit">Добавить</button>
    </form>
  );
}

Кратко:

  • Не нужно писать отдельный fetch.
  • Нет явного API-эндпоинта — функция вызывается как бы "изнутри" Next.js.
  • Удобно для простых форм, мутаций, когда не требуется интеграция с внешними клиентами.

3. Отличия Server Actions и API Routes (Route Handlers)

Давайте разложим по полочкам и сравним два подхода.

Характеристика API Routes (Route Handlers) Server Actions
Вызов из браузера Через fetch, axios и т.д. Через <form action={...}> или программно (React)
Доступность извне Доступны по HTTP любому клиенту Только из Next.js компонентов
Архитектура Явные REST/HTTP эндпоинты Серверные функции
Обработка данных req.json(), req.body, req.query formData (или параметры)
Поддержка методов GET, POST, PUT, DELETE и др. Обычно POST (мутации)
Валидация, авторизация Любая, вручную Аналогично, но проще интегрировать с формами
Интеграция с внешним Да (мобильные, сторонние клиенты) Нет

В чём фундаментальная разница?

  • API Routes — это полноценные HTTP-эндпоинты, которые можно дергать из любого места (даже из curl или Postman).
  • Server Actions — это "приватные" серверные функции, которые доступны только вашему Next.js-приложению, и только через формы/компоненты.

Аналогия

  • API Routes — как дверь в ваш дом: через неё могут войти и вы, и гости, и курьер, и даже соседский кот (если знает адрес).
  • Server Actions — как потайной ход, ведущий только в вашу комнату, и только вы знаете, где он находится.

4. Когда использовать Server Actions

Server Actions отлично подходят для:

  • Обработки форм: когда пользователь что-то отправляет, и вы хотите сразу обработать данные на сервере.
  • Мутаций данных: добавление, изменение, удаление (например, добавить задачу, удалить комментарий).
  • Внутренней бизнес-логики: когда не требуется внешний доступ к API.
  • Минимизации boilerplate: меньше кода, не нужно писать fetch, не нужно думать о маршрутах.

Пример:
Вы делаете TODO-приложение, где пользователь может добавить задачу через форму. Используйте Server Action:

<form action={addTodo}>
  <input name="title" />
  <button>Добавить</button>
</form>

Всё — никаких fetch, никаких ручных API-запросов.

5. Когда использовать API Routes (Route Handlers)

API Routes (Route Handlers) нужны, когда:

  • Нужен внешний API: ваше приложение должно быть доступно мобильным клиентам, другим фронтендам, интеграциям.
  • Требуется поддержка разных HTTP-методов: например, GET для получения данных, PUT/DELETE для обновления/удаления.
  • Требуется сложная маршрутизация: например, /api/users/[id].
  • Нужно реализовать REST или GraphQL API для сторонних клиентов.
  • Вам нужно разделить серверную логику и фронтенд: например, когда фронтенд и бэкенд разрабатывают разные команды.

Пример:
У вас есть мобильное приложение, которое должно получать и отправлять данные на сервер. Вы реализуете API Routes, чтобы ваше Next.js-приложение выступало как полноценный сервер.

6. Как Server Actions и API Routes могут работать вместе

В реальных проектах часто используются оба подхода.

Пример сценария:

  • Для пользовательских форм и внутренней логики используете Server Actions.
  • Для интеграций с внешними сервисами или мобильными приложениями — API Routes.

Можно даже вызывать API Routes из Server Actions, если нужно переиспользовать бизнес-логику, или наоборот.

Пример: Server Action вызывает API Route

// app/actions/addUser.ts
'use server';

export async function addUser(formData) {
  const name = formData.get('name');
  // Вызываем API Route через fetch (локально)
  const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/users`, {
    method: 'POST',
    body: JSON.stringify({ name }),
    headers: { 'Content-Type': 'application/json' }
  });
  return await res.json();
}

Пример: API Route использует бизнес-логику из Server Action

Можно вынести бизнес-логику в отдельный модуль и импортировать её и в API Route, и в Server Action.

// app/lib/userService.ts
export async function createUser(name) {
  // ...добавление пользователя в БД
}

// app/api/users/route.ts
import { createUser } from '../../lib/userService';

export async function POST(request) {
  const { name } = await request.json();
  await createUser(name);
  return NextResponse.json({ success: true });
}

// app/actions/addUser.ts
'use server';
import { createUser } from '../lib/userService';

export async function addUser(formData) {
  const name = formData.get('name');
  await createUser(name);
}

7. Практические рекомендации: что выбрать?

Когда лучше Server Actions:

  • Вся логика внутри вашего Next.js-приложения.
  • Нет необходимости открывать API вовне.
  • Нужно просто и быстро обработать форму.
  • Вы хотите использовать преимущества Server Components (минимизация клиентского JS, SSR).

Когда лучше API Routes:

  • Требуется внешний API.
  • Нужно поддерживать разные HTTP-методы.
  • Необходимо масштабировать серверную часть отдельно от фронта.
  • Используется сторонний клиент (например, мобильное приложение).

Можно ли использовать только Server Actions?
Если вы разрабатываете только веб-приложение на Next.js, и не планируете открывать API для внешних клиентов — да, можно! Но если есть хотя бы малейший шанс, что API понадобится другим приложениям — лучше сразу проектировать логику через Route Handlers.

8. Типичные ошибки при выборе между Server Actions и API Routes

Ошибка №1: попытка вызвать Server Action из внешнего клиента.
Server Actions доступны только из компонентов Next.js. Если вы попробуете сделать fetch на Server Action — ничего не получится, она не "открыта" наружу.

Ошибка №2: избыточное дублирование кода.
Если бизнес-логика реализована и в Server Action, и в API Route, не копируйте её — выносите в отдельный модуль и переиспользуйте.

Ошибка №3: использование Server Actions для публичных API.
Если нужно, чтобы API был доступен снаружи (например, для мобильного приложения), используйте Route Handlers.

Ошибка №4: попытка использовать GET-запросы с Server Actions.
Server Actions ориентированы на мутации (POST), для получения данных используйте Server Components или API Routes.

Ошибка №5: смешивание клиентского и серверного кода.
Не пытайтесь импортировать Server Action в Client Component без use server — получите ошибку компиляции.

Ошибка №6: забыли про ограничения Server Actions.
Server Actions нельзя вызывать из fetch, нельзя использовать для SSR данных, которые должны быть доступны по прямому HTTP-запросу.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ