Next.js 14 و Server Actions
Server Action ها چطور کار میکنن، چرا یک درخواست هم mutation و هم UI تازه رو برمیگردونه، و چه نکات امنیتیای رو نباید فراموش کرد.

Server Actions چی هستن؟
Server Action یک تابع async است که بهجای اجرا روی مرورگر، مستقیم روی سرور اجرا میشود؛ Next.js آن را از طریق مکانیزم اکشنهای React (مثل <form action>) صدا میزند. برای تعریفش کافی است دستور 'use server' را بالای تابع یا بالای یک فایل جدا بگذارید:
'use server'
import { revalidatePath } from 'next/cache'
export async function createPost(formData) {
await db.post.create({
data: { title: formData.get('title') },
})
revalidatePath('/posts')
}
این تابع را میشود مستقیم به action یک فرم داد، بدون نیاز به ساختن یک API route جدا:
<form action={createPost}>
<input name="title" />
<button type="submit">ارسال</button>
</form>
یک درخواست، هم داده هم UI جدید
نکتهی جالب Server Action ها این است که وقتی داخلش revalidatePath، updateTag یا redirect صدا زده شود، Next.js توی همان یک درخواست HTTP هم اکشن را اجرا میکند و هم صفحه را دوباره روی سرور رندر میکند؛ نتیجه در قالب یک RSC Payload برمیگردد و کلاینت بدون فچ اضافه، رابط کاربری تازه را نشان میدهد.
ترتیب اجرا روی کلاینت
Next.js اکشنها را برای هر کلاینت بهترتیب (sequential) اجرا میکند، نه موازی. یعنی اگر کاربر پشت سر هم چند اکشن را صدا بزند، دومی منتظر تمام شدن اولی میماند. اگر به اجرای موازی نیاز دارید، باید آن را داخل خود اکشن یا با فچ موازی در یک Server Component انجام بدهید.
نکات امنیتی که نباید فراموش کرد
هر Server Action دقیقاً مثل یک endpoint عمومی است که با POST قابل دسترسی است — یعنی هر کسی که بتواند همان درخواست را بفرستد میتواند اکشن را صدا بزند، حتی بدون رد شدن از UI. Next.js چند محافظت خودکار دارد (بررسی CSRF بر اساس Origin/Host، محدودیت حجم بدنهی درخواست، رمزنگاری شناسهی اکشنها)، ولی اینها جایگزین بررسیهای خودتان نیستند. داخل هر اکشن حتماً باید:
- کاربر را authenticate و authorize کنید (رندر مشروط فرم کافی نیست)
- ورودی FormData را معتبرسنجی کنید، چون کاملاً غیرقابلاعتماد است
- فقط دادهی لازم را برگردانید، نه رکورد خام دیتابیس
انتخاب روش رفرش کش
برای تازه کردن کش بعد از یک mutation چند گزینه هست:
updateTag: بلافاصله تگ را invalidate میکند و همان درخواست منتظر دادهی تازه میماندrevalidateTag: با مدل stale-while-revalidate کار میکند، یعنی کاربر فعلی دادهی قدیمی را میبیند و رفرش در پسزمینه انجام میشودrevalidatePath: وقتی فقط یک مسیر مشخص تحت تاثیر قرار گرفته، سادهترین گزینه است
جمعبندی
Server Actions مسیر ساخت فرمها و mutation ها را کوتاهتر میکند: بدون API route جدا، با امنیت پایه از طرف فریمورک، و امکان رفرش همزمان UI. ولی هیچکدام از اینها جای احراز هویت و اعتبارسنجی دستی داخل خود اکشن را نمیگیرد.



