Nextjs Route Handlers Server Actions Caching Revalidation Tags Data Mutation Flow
Definisi
Route Handler adalah endpoint API di dalam Next.js App Router (file route.ts di dalam app/). Server Action adalah fungsi async yang dijalankan di server dan bisa dipanggil langsung dari komponen React (form atau event handler). Keduanya dipakai untuk mutasi data, tapi punya tempat yang beda.
Kapan dipakai
- Route Handler: butuh endpoint HTTP eksplisit (Webhook, API eksternal, akses programatik, kontrol method
GET/POST/PUT/DELETEmanual). - Server Action: mutasi yang dipicu dari UI (submit form, tombol simpan) dan ingin langsung revalidate cache tanpa fetch manual dari client.
Kalau ragu, mutasi dari form lebih enak pakai Server Action; endpoint untuk client lain pakai Route Handler.
Cara kerja
Route Handler
// app/api/orders/route.ts
import { NextResponse } from 'next/server';
export async function POST(req: Request) {
const body = await req.json();
const order = await createOrder(body);
return NextResponse.json(order, { status: 201 });
}Server Action
// app/actions.ts
'use server';
export async function createOrder(formData: FormData) {
const order = await repo.create({
total: Number(formData.get('total')),
});
revalidatePath('/orders');
revalidateTag('orders');
return order;
}Dipanggil dari form:
<form action={createOrder}>
<input name="total" />
<button type="submit">Buat</button>
</form>Revalidation
revalidatePath('/orders')membersihkan cache halaman/path tertentu.revalidateTag('orders')membersihkan semua fetch yang menaruhtags: ['orders'].revalidateTaglebih fleksibel kalau data sama dipakai di banyak halaman.
Struktur alur mutasi
Loading diagram...
Contoh fetch dengan tag
async function getOrders() {
const res = await fetch('/api/orders', {
next: { tags: ['orders'] },
});
return res.json();
}Setelah Server Action memanggil revalidateTag('orders'), pemanggilan getOrders() berikutnya akan mengambil data segar.
Catatan implementasi
- Server Action wajib diawali
'use server'di file atau di atas fungsi. - Jangan kirim secret ke client lewat Server Action return; return hanya data yang aman.
revalidatePathmenerima path persis; untuk dynamic route pakai'/orders/[id]'ataurevalidateTag.- Route Handler di App Router tidak lagi pakai
pages/api; fileroute.tslangsung di dalamapp.
Kesalahan umum
- Cache tidak update: lupa
revalidatePath/revalidateTag, halaman tetap menampilkan data lama. - Server Action dipakai sebagai API publik: Server Action bukan pengganti endpoint; jangan ekspos ke client eksternal.
- Mutasi di Route Handler tanpa auth: endpoint POST terbuka, siapa saja bisa mengirim data.
- Over-revalidate:
revalidatePath('/')terlalu luas mematikan cache hampir semua halaman.