JavaRush /Курсы /Модуль 4: Node.js, Next.js и Angular /Финальная лекция по Next.JS

Финальная лекция по Next.JS

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

1. Вспоминаем, что мы изучили

Итак, мы фактически научились строить полный цикл взаимодействия: от пользователя в браузере до вашего Node.js-сервера и обратно, используя самые современные и эффективные подходы в Next.js.

Допустим, что вы строите дом.

  • Route Handlers — это как прочная внешняя лестница, которая ведёт к задней двери вашего дома. Через неё могут зайти любые "гости" (другие приложения, мобильные клиенты, другие части вашего же фронтенда), передать "посылки" (данные) и получить "ответы". Она универсальна и понятна всем. Вы задаёте чёткие правила: "для посылок типа POST сюда", "для GET туда".
  • Server Actions — это как секретный телепорт, встроенный прямо в вашу мебель в гостиной. Вы просто нажимаете кнопку (отправляете форму), и данные мгновенно переносятся прямо на сервер, делают своё дело, а результат появляется обратно, не требуя от вас ручной прокладки проводов (fetch-запросов). Он выглядит как обычная кнопка, но внутри — магия!

Обе эти технологии — Route Handlers и Server Actions — работают на Node.js, но по-разному интегрированы в Next.js. Они позволяют нам перенести тяжёлую работу (доступ к базе данных, сложные вычисления, обработка файлов) с клиентского браузера на сервер, где она выполняется быстрее и безопаснее.

Пример: Как это выглядит в нашем приложении (концептуально)

Давайте представим, что наше приложение — это "Список дел".

Создание задачи (через Server Action):
Мы могли бы иметь форму на странице, где пользователь вводит текст задачи. При отправке формы, вместо того чтобы вручную делать fetch('/api/todos'), мы просто указываем action={createTodo}. Функция createTodo на сервере получает данные, сохраняет их (например, в файл или базу данных), и Next.js сам обновляет UI.

// app/add-todo/page.tsx
import { addTodo } from './actions'; // Импортируем Server Action

export default function AddTodoPage() {
  return (
    <form action={addTodo}> {/* Прямая привязка к Server Action */}
      <input type="text" name="title" placeholder="Что нужно сделать?" />
      <button type="submit">Добавить задачу</button>
    </form>
  );
}

// app/add-todo/actions.ts
'use server'; // Директива, указывающая, что это Server Action

import fs from 'fs/promises';
import path from 'path';

export async function addTodo(formData: FormData) {
  const title = formData.get('title') as string;
  if (!title) {
    throw new Error('Название задачи не может быть пустым!');
  }
  // ... логика сохранения задачи, например, в JSON файл
  const filePath = path.join(process.cwd(), 'data', 'todos.json');
  const data = await fs.readFile(filePath, 'utf8');
  const todos = JSON.parse(data);
  todos.push({ id: Date.now(), title, completed: false });
  await fs.writeFile(filePath, JSON.stringify(todos, null, 2));

  console.log('Задача добавлена на сервере!');
}

Получение списка задач (через Route Handler):
Если другому приложению (или даже нашему же, но в другом месте, где Server Actions не подходят) нужен список задач, мы можем обратиться к API-эндпоинту:

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

export async function GET() {
  try {
    const filePath = path.join(process.cwd(), 'data', 'todos.json');
    const data = await fs.readFile(filePath, 'utf8');
    const todos = JSON.parse(data);
    return NextResponse.json(todos, { status: 200 });
  } catch (error) {
    console.error('Ошибка при чтении задач:', error);
    return NextResponse.json({ message: 'Ошибка сервера' }, { status: 500 });
  }
}

И этот эндпоинт будет доступен по адресу /api/todos. Любой, кто отправит GET-запрос по этому адресу, получит список задач в формате JSON.

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

2. Часто задаваемые вопросы

Теперь давайте разберем те вопросы, которые, я уверен, возникают в вашей голове, когда речь заходит о Server Actions и Route Handlers. Это, пожалуй, самый "горячий" и дискуссионный момент этого модуля.

Когда использовать Route Handlers (API Routes), а когда Server Actions?

Это самый главный вопрос! И, как это часто бывает в программировании, ответ: "Зависит от ситуации".

Используйте Route Handlers (API Routes), когда:

  • Вы строите полноценный REST API, который будет использоваться не только вашим Next.js-приложением, но и:
    • Мобильными приложениями (iOS, Android).
    • Сторонними сервисами.
    • Другими фронтенд-приложениями (например, на React без Next.js).
    • Вам нужен более традиционный API-слой для интеграции.
  • Вам нужны HTTP-методы (GET, POST, PUT, DELETE) и HTTP-статусы в их классическом понимании для каждого запроса. Route Handlers строго следуют HTTP-спецификации.
  • Вам нужен контроль над заголовками запроса/ответа, CORS и прочими низкоуровневыми аспектами HTTP.
  • Вы работаете с файлами, особенно с большими файлами или потоковой передачей, где нужен прямой контроль над телом запроса/ответа.
  • Вам нужна публичная, документированная точка входа для данных, к которой могут обращаться кто угодно, при наличии прав.

Используйте Server Actions, когда:

  • Вы выполняете мутации данных (CRUD операции) в рамках форм в вашем Next.js-приложении. Это самый распространённый и удобный сценарий. action={myServerAction} — и всё работает!
  • Вы хотите максимально упростить взаимодействие между клиентским компонентом и сервером, минимизировав количество шаблонного кода (fetch, парсинг JSON, обработка ошибок сетевых запросов). Server Actions абстрагируют большую часть этой рутины.
  • Вам нужен "оптимистичный UI" (useOptimistic) или удобное управление состоянием формы (useFormState). Эти хуки React напрямую интегрированы с Server Actions.
  • Ваша серверная логика тесно связана с конкретными компонентами UI. Например, кнопка "Лайк" на посте — её действие может быть Server Action.
  • Вам нужно избежать дополнительных сетевых запросов в браузере при отправке формы, так как Server Actions используют прямую POST-передачу данных без AJAX (хотя под капотом Next.js это все же делает).

3. Сводная таблица сравнения

Давайте сведем все это в одну небольшую, но очень полезную таблицу:

Характеристика Route Handlers (API Routes) Server Actions
Основное назначение Построение универсального REST API Выполнение серверной логики напрямую из компонентов/форм
HTTP-методы Чётко определены: GET, POST, PUT, DELETE и др. Всегда POST (для безопасности), остальные методы неявно внутри действия
Интеграция с UI Через fetch() на клиенте Прямое подключение к form action или вызов из любого компонента
Взаимодействие с внешними клиентами Отлично подходит для мобильных, других фронтендов В основном для взаимодействия между клиентским кодом Next.js и сервером Next.js
Кеширование Можно контролировать кеширование HTTP-заголовками Интегрированы с системой кеширования Next.js (revalidatePath, revalidateTag)
Обработка ошибок Возврат NextResponse.json({ message: 'Error' }, { status: 400 }) throw new Error(), обработка через useFormState или error.tsx
Оптимистичный UI Требует ручной реализации с fetch Встроенная поддержка через useOptimistic
Валидация данных Обычно на сервере (например, zod) Обычно на сервере (например, zod), часто интегрирована с useFormState
Сложность внедрения Чуть больше шаблонного кода (fetch, парсинг, try/catch) Меньше шаблонного кода, "магическая" интеграция
Когда выбирать Для публичных API, интеграции, строгих REST-конвенций Для обработки форм, мутаций данных, интерактивности внутри Next.js-приложения

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

4. Как ваш проект развивать дальше?

С этими знаниями, ваше учебное приложение может стать по-настоящему интерактивным. Мы можем:

  • Добавить формы для создания, редактирования и удаления студентов/задач.
  • Реализовать API для получения списка студентов, который можно использовать на отдельной странице админки или даже в мобильном приложении.
  • Применять useOptimistic для мгновенного обновления интерфейса при добавлении новой задачи, даже если сервер ещё не ответил, создавая ощущение невероятной скорости.
  • Добавить валидацию форм, чтобы пользователи не могли ввести некорректные данные.

Вы перешли от простого отображения статических данных к полноценному динамическому веб-приложению, способному взаимодействовать с серверной частью! Думаю вам понравилось изучать Next, а работать с ним понравиться еще больше!

1
Задача
Модуль 4: Node.js, Next.js и Angular, 12 уровень, 9 лекция
Недоступна
API для списка задач (To-Do List, только GET и POST)
API для списка задач (To-Do List, только GET и POST)
1
Задача
Модуль 4: Node.js, Next.js и Angular, 12 уровень, 9 лекция
Недоступна
Детальный просмотр и удаление задачи (GET, DELETE, динамические сегменты)
Детальный просмотр и удаление задачи (GET, DELETE, динамические сегменты)
1
Задача
Модуль 4: Node.js, Next.js и Angular, 12 уровень, 9 лекция
Недоступна
Простое API для заметок с валидацией данных
Простое API для заметок с валидацией данных
1
Задача
Модуль 4: Node.js, Next.js и Angular, 12 уровень, 9 лекция
Недоступна
API для пользователей: редактирование и обработка ошибок (PUT, обработка статусов)
API для пользователей: редактирование и обработка ошибок (PUT, обработка статусов)
1
Задача
Модуль 4: Node.js, Next.js и Angular, 12 уровень, 9 лекция
Недоступна
Мини-блог с Route Handlers: посты, комментирование, обработка ошибок и клиентская логика
Мини-блог с Route Handlers: посты, комментирование, обработка ошибок и клиентская логика
3
Опрос
Валидация данных, 12 уровень, 9 лекция
Недоступен
Валидация данных
Валидация данных
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ