Навіщо фронтенд-розробникам знання бекенду: розбираємося з 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, ви перестаєте бути тим, хто лише стилізує компоненти, і стаєте справжнім продуктовим інженером — здатним безпечно й ефективно спроєктувати фічу від рядка в базі даних аж до пікселя в браузері.
