// 1. SERVER ACTION: Excelent pentru formulare și mutații interne
// app/actions/user.ts
'use server';
import { revalidatePath } from 'next/cache';
import { db } from '@/lib/db';
export async function updateBio(prevState: any, formData: FormData) {
const bio = formData.get('bio') as string;
if (!bio || bio.length > 500) return { error: 'Bio prea lung' };
await db.user.update({ where: { id: 1 }, data: { bio } });
revalidatePath('/profile');
return { success: true };
}
// 2. ROUTE HANDLER: Necesar pentru webhook-uri externe (ex: Stripe)
// app/api/webhooks/stripe/route.ts
import { NextResponse } from 'next/server';
export async function POST(req: Request) {
const body = await req.text();
const signature = req.headers.get('stripe-signature');
if (!signature) {
return NextResponse.json({ error: 'Missing signature' }, { status: 400 });
}
// Webhook-ul extern nu poate apela un Server Action!
return NextResponse.json({ received: true });
}Când au apărut Server Actions în Next.js 13.4, mulți colegi au crezut că API Routes au murit. Am făcut și eu greșeala asta la primul proiect migrat în App Router — am vrut să bag absolut totul în acțiuni de server, iar la 2 săptămâni distanță refăceam arhitectura pentru că mă izbeam de limite de timeout pe Vercel și erori ciudate la încărcarea fișierelor.
După mai bine de un an cu ambele abordări în producție pe o aplicație cu peste 20k utilizatori activi, lucrurile s-au așezat. Nu e vorba despre care metodă e mai nouă, ci despre ce problemă tehnică încerci să rezolvi.
Form Submissions și mutații simple: Server Actions câștigă detașat
Dacă ai un formular de login, o editare de profil sau o mutație simplă în baza de date, Server Actions sunt genial de comode. Scapi de tot codul boilerplate: nu mai scrii fetch('/api/user'), nu mai gestionezi manual stări complexe de loading dacă folosești useActionState și primești tipizare directă între server și UI.
Plus că ai revalidatePath și revalidateTag direct în acțiune. Ai dat submit, ai salvat în Postgres, ai apelat revalidarea și UI-ul s-a actualizat instant fără să pasezi token-uri sau să reîncarci query-uri de SWR sau React Query.
La o aplicație SaaS la care lucrez, unde aveam în jur de 30 de formulare mici de setări, trecerea pe Server Actions ne-a redus codul de frontend cu aproape 35% și am șters 12 API routes redundante.
File Uploads: Unde Server Actions încep să scârțâie
Aici mulți își fură căciula. Dacă încerci să trimiți un fișier de 50MB printr-un Server Action ca FormData, tot fișierul ăla trece prin lambda-ul de Next.js. Pe Vercel ai o limită strictă de request body pe serverless (de obicei 4.5MB), iar dacă utilizatorul e pe o conexiune mai slabă, acțiunea va da timeout înainte să termine de citit buffer-ul.
Ce fac eu în producție? Dacă e vorba de un avatar mic de 200KB, merge fără probleme printr-un Server Action. Dar pentru orice înseamnă documente PDF, clipuri video sau fișiere mari, folosesc un API Route (Route Handler) care generează un pre-signed URL pentru AWS S3 sau Cloudflare R2. Clientul ia acel URL și face PUT direct în bucket. Zero presiune pe serverul de Next.js, zero runde inutile de payload prin acțiuni.
Webhooks și consumatori externi: Exclusiv API Routes
Asta e o regulă simplă și clară: dacă apelul HTTP vine din exteriorul aplicației tale React, nu poți folosi Server Actions.
Server Actions sunt practic un protocol RPC intern creat pentru comunicarea dintre React Server Components și clientul de React. Au nevoie de headere speciale ale framework-ului și așteaptă un format de răspuns intern. Un webhook trimis de Stripe, Resend sau Twilio nu știe ce e ăla next-action header și va eșua mizerabil.
Pentru webhooks, integrări cu microservicii externe sau dacă vrei să expui un endpoint pentru o aplicație mobilă nativă, Route Handlers (app/api/.../route.ts) rămân singura opțiune corectă.
Cu ce rămânem?
- Server Actions: Formulare, mutații de date interne, acțiuni UI unde vrei revalidare instantă de cache.
- API Routes: Webhooks, generare de pre-signed URLs pentru fișiere mari, endpoints publice sau integrări cu aplicații mobile.
Tu câte API routes ai refactorizat în Server Actions până acum și unde te-ai lovit de zid?