eduardweb.
Server ActionsIntermediar#server-actions#nextjs#backend#api-routes

Server Actions vs API Routes în Next.js: Din tranșee, când o dăm în bară

De Liliana Ghiță, 11 iul. 2026 · 9 vizualizări · 2 like-uri

Postat 11 iul. 2026
typescript
import { NextResponse } from 'next/server';

export async function POST(req: Request) {
  const payload = await req.text();
  const signature = req.headers.get('stripe-signature');

  if (!signature) {
    return NextResponse.json({ error: 'Missing signature' }, { status: 400 });
  }

  // Într-un Server Action nu ai acces direct la raw body-ul request-ului
  // necesar pentru verificarea semnăturii criptografice Stripe.
  try {
    // Aici s-ar face verificarea: stripe.webhooks.constructEvent(...)
    console.log('Webhook primit cu succes');
    return NextResponse.json({ received: true });
  } catch (err) {
    return NextResponse.json({ error: 'Webhook handler failed' }, { status: 400 });
  }
}

M-am lovit de dilema asta pe un proiect recent cu vreo 12.000 de utilizatori activi, unde echipa a vrut să trecem absolut totul pe Server Actions pentru că "e la modă". Spoiler alert: ne-am spart capul în câteva scenarii unde rutele clasice de API erau sfinte și am fost nevoiți să facem rollback parțial.

Next.js ne dă ambele unelte, dar granița dintre ele e uneori neclară pentru mulți devși. Hai să le luăm la bani mărunți pe cazuri concrete, ca să nu repetați greșelile noastre.

Formularul simplu: Unde Server Actions domină complet

Pentru un formular clasic de contact sau editare profil, Server Actions sunt geniale. Am eliminat complet scrierea de fetch('/api/profile', { method: 'POST', body ... }) și gestiunea manuală a stărilor de loading cu useState.

Trimiți direct funcția în atributul action al tagului <form>. Ce am câștigat? Tipizare cap-coadă cu TypeScript direct din baza de date până în UI și zero boilerplate. Am redus codul cu vreo 35% pe formularele de setări.

Trade-off: Dacă ai nevoie de un progres foarte granular (gen "salvare în ciornă" la fiecare keystroke), Server Actions pot deveni greoaie și e mai simplu să controlezi tu request-urile manual cu un debounce clasic pe o rută API.

Upload de fișiere: Capcana în care am picat noi

Aici am făcut prima greșeală majoră. Am încercat să facem upload de imagini de profil (până în 10MB) direct printr-un Server Action. Server Actions trec prin protocolul de POST multipart de la Next.js, care serializează datele într-un format destul de ciudat.

Pe serverless (Vercel), ne loveam constant de timeout-uri și de limita de dimensiune a payload-ului (care e de 4.5MB pe planurile standard). În plus, procesarea unui fișier mare blochează serverul Node degeaba.

Cum am rezolvat? Am revenit la o rută API clasică (/api/upload) care generează un presigned URL de S3, iar clientul face upload-ul direct în cloud. Server Actions sunt groaznice pentru procesat stream-uri de fișiere mari; folosiți-le doar pentru fișiere minuscule (sub 1MB) sau deloc în scenariul ăsta.

Webhook-uri de la terți: API Routes sunt singura opțiune

Dacă integrezi Stripe, Shopify sau orice alt serviciu care îți trimite un webhook când se confirmă o plată, Server Actions ies complet din discuție.

De ce? Pentru că un webhook are nevoie de un endpoint HTTP standard (un URL static de tip POST) pe care serviciul extern să îl poată apela liber. Server Actions sunt create special pentru interacțiunea client-server din interiorul aplicației tale Next.js. Ele folosesc headere speciale și o structură de request internă pe care Stripe nu o va înțelege niciodată.

Pentru webhook-uri, creează mereu o rută în /app/api/webhooks/stripe/route.ts. Acolo poți valida semnătura Stripe, poți citi raw body-ul (esențial pentru securitate) și poți trimite un status code 200 OK curat.

Concluzia mea simplă

După un an de Next.js în producție cu ambele abordări, regula mea de aur este:

  • Folosesc Server Actions pentru tot ce înseamnă interacțiune directă a userului cu baza de date din pagină (mutări de date, modificări de status, formulare).
  • Păstrez API Routes pentru upload-uri mari, integrări cu terți (webhooks) și atunci când am nevoie ca API-ul meu să fie consumat de o aplicație mobilă externă.

Voi cum ați împărțit arhitectura? Ați trecut complet pe Server Actions sau încă mai scrieți rute de API pentru formulare?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.