Навіщо фронтенд-розробникам знання бекенду: розбираємося з API Routes і Server Actions у Next.js

Докладний гайд для фронтенд-інженерів про розмиту межу між клієнтом і сервером у Next.js: API Routes, Server Actions і практичні архітектурні патерни для full-stack розробки.

Vladyslav Tsyvinda
Vladyslav Tsyvinda
·Оновлено
Обкладинка: Навіщо фронтенд-розробникам знання бекенду: розбираємося з API Routes і Server Actions у Next.js

Навіщо фронтенд-розробникам знання бекенду: розбираємося з API Routes і Server Actions у Next.js

Роками розподіл обов’язків у веброзробці був кришталево чистим: фронтенд-розробники відповідали за браузер (HTML, CSS, JavaScript і стан UI), а бекенд-розробники — за сервер, бази даних, маршрутизацію та бізнес-логіку. Ви створювали інтерфейс, вони — API-ендпоінти, а зустрічалися ви посередині, у запиті fetch().

Проте сучасна веб-екосистема на чолі з метафреймворками на кшталт Next.js цю стіну фактично зруйнувала. Сьогодні, щоб бути по-справжньому ефективним фронтенд-інженером, потрібно добре розуміти концепції бекенду. Next.js нативно долає цей розрив за допомогою API Routes і Server Actions, буквально за одну ніч перетворюючи фронтенд-розробників на full-stack продуктових інженерів.

Розберімося, чому знання бекенду більше не є опційними, і як опанувати два основні серверні механізми Next.js.


1. Зміна парадигми: чому лише фронтенду вже недостатньо

Коли ви створюєте класичний Single Page Application (SPA) на чистому React (наприклад, через Vite), уся ваша кодова база компілюється й відправляється в браузер користувача. Для інтерактивних станів на клієнті це чудово, але має серйозну ціну:

  • Ризики безпеки: на клієнті неможливо безпечно зберігати API-ключі, облікові дані бази даних чи платіжні секрети. Будь-хто може відкрити DevTools у браузері й витягнути їх.
  • Накладні витрати на продуктивність: браузер мусить завантажити, розпарсити й виконати величезні JavaScript-бандли, перш ніж користувач побачить хоч якісь дані.
  • Проблеми з SEO: пошуковим ботам часто важко індексувати контент, який повністю залежить від асинхронного отримання даних на клієнті.

Розуміючи бекенд, фронтенд-розробники можуть точно вирішувати, де має виконуватися код. Next.js дає змогу тримати захищені й «важкі» з погляду даних операції на сервері, відправляючи клієнту лише чистий, попередньо відрендерений HTML і мінімум JavaScript.


2. Класична серверна логіка: API Routes у Next.js

API Routes — класичний спосіб створити бекенд прямо всередині застосунку на Next.js. Вони поводяться так само, як традиційний бекенд на Node.js/Express, але використовують файлову маршрутизацію в директорії app/api/.

Коли використовувати API Routes:

  • Коли ви створюєте публічний API, який мають споживати зовнішні мобільні застосунки чи сторонні сервіси.
  • Коли обробляєте стандартні HTTP-вебхуки (наприклад, слухаєте події платежів від Stripe).
  • Коли потрібна традиційна RESTful-архітектура з явними методами GET, POST, PUT і DELETE.

Практичний приклад: створюємо захищений ендпоінт для користувачів

Замість того щоб відкривати клієнт бази даних браузеру, ми створюємо API-маршрут, який безпечно виконує запит до бази на боці сервера.

// src/app/api/users/route.tsimport { NextRequest, NextResponse } from 'next/server';import { db } from '@/shared/lib/db'; // Your database client (e.g., Prisma)export async function GET(request: NextRequest) {  try {    // This code runs strictly on the server    const users = await db.user.findMany({      select: { id: true, name: true, email: true }    });        return NextResponse.json({ success: true, data: users }, { status: 200 });  } catch (error) {    return NextResponse.json({ success: false, message: 'Internal Server Error' }, { status: 500 });  }}

На фронтенді ви споживаєте його так само, як будь-який зовнішній API-ендпоінт: fetch('/api/users'). Облікові дані вашої бази даних залишаються повністю прихованими від браузера клієнта.


3. Full-stack революція: Server Actions у Next.js

Server Actions, що з’явилися як проривна можливість сучасних React і Next.js, дають змогу оголошувати асинхронні серверні функції, які можна викликати безпосередньо з клієнтських UI-компонентів. Вони повністю позбавляють потреби вручну писати API-ендпоінти, fetch-запити та парсинг JSON для базових мутацій.

Коли використовувати Server Actions:

  • Надсилання форм (наприклад, створення допису чи оновлення профілю).
  • Інтерактивні UI-компоненти, що змінюють стан на сервері (наприклад, натискання кнопки «Подобається» чи перемикання статусу).
  • Операції, тісно пов’язані з вашим UI, які потребують автоматичної ревалідації даних (миттєвого оновлення сторінки після зміни даних).

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

Спершу оголошуємо server action в окремому файлі з директивою 'use server' на початку. Вона повідомляє інструменту збірки, що ця функція має виконуватися виключно на бекенді.

// src/services/auth.actions.ts'use server';import { db } from '@/shared/lib/db';import { revalidatePath } from 'next/cache';export async function updateUserProfile(userId: string, formData: FormData) {  const name = formData.get('name') as string;    // Perform secure backend validation and DB updates  await db.user.update({    where: { id: userId },    data: { name }  });  // Automatically clear the cache and update the UI data on the screen  revalidatePath('/profile');}

А тепер погляньте, наскільки чистим стає клієнтський компонент. Ми передаємо action безпосередньо в стандартний атрибут action HTML-форми. Жодного useState для станів завантаження, жодних обробників onSubmit і жодного налаштування API-запитів!

// src/components/ProfileForm.tsx'use client';import { updateUserProfile } from '@/services/auth.actions';export function ProfileForm({ userId }: { userId: string }) {  // Bind the userId parameter to our server action safely  const updateUserWithId = updateUserProfile.bind(null, userId);  return (    <form action={updateUserWithId} className="flex flex-col gap-4">      <label>        <span>Update Profile Name:</span>        <input type="text" name="name" required className="border p-2 rounded" />      </label>      <button type="submit" className="bg-orange-500 text-white p-2 rounded">        Save Changes      </button>    </form>  );}

4. API Routes чи Server Actions: коротке порівняння

Щоб правильно структурувати свої full-stack застосунки на Next.js, користуйтеся цим простим архітектурним орієнтиром:

Характеристика API Routes (/api/*) Server Actions ('use server')
Основне призначення Надання ендпоінтів зовнішнім споживачам / вебхукам. Обробка внутрішніх UI-взаємодій і мутацій через форми.
Спосіб виклику Стандартні HTTP fetch-запити з клієнта (за URL). Пряме виконання JavaScript-функції у стилі RPC.
Формат даних Потребує явної обробки JSON у запитах і відповідях. Нативні JavaScript-аргументи, об’єкти та FormData.
Інтеграція з кешуванням Потрібні ручні заголовки керування кешем. Глибока інтеграція з revalidatePath і revalidateTag.

Висновок: приймаємо full-stack мислення

Розуміння принципів бекенду не означає, що фронтенд-розробник має за одну ніч стати адміністратором баз даних чи DevOps-інженером. Це означає розуміти безпеку даних, бюджети продуктивності, життєвий цикл кешу та межі мережевої взаємодії.

Опанувавши API Routes і Server Actions у Next.js, ви перестаєте бути тим, хто лише стилізує компоненти, і стаєте справжнім продуктовим інженером — здатним безпечно й ефективно спроєктувати фічу від рядка в базі даних аж до пікселя в браузері.