هندلرهای مسیر
هندلرهای مسیر به شما امکان می دهند با استفاده از API های وب Request (opens in a new tab) و Response (opens in a new tab) درخواست های سفارشی برای یک مسیر خاص ایجاد کنید.

خوب است بدانید: هندلرهای مسیر فقط داخل پوشه
appدر دسترس هستند. آن ها معادل API Routes ها در پوشهpagesهستند، به این معنی که نیازی به استفاده همزمان از API Route و Route Handler نیست.
قرارداد
هندلرهای مسیر در یک فایل route.js|ts داخل پوشه app تعریف می شوند.
export const dynamic = 'force-dynamic' // defaults to auto
export async function GET(request: Request) {}هندلرهای مسیر را می توان مشابه page.js و layout.js داخل پوشه app تودرتو کرد. اما نمی تواند یک فایل route.js در همان سطح segment مسیر به عنوان page.js وجود داشته باشد.
متدهای HTTP پشتیبانی شده
روش های HTTP methods (opens in a new tab) GET، POST، PUT، PATCH، DELETE، HEAD و OPTIONS پشتیبانی می شوند. اگر از روشی که پشتیبانی نمی شود استفاده شود، Next.js پاسخی با کد ۴۰۵ (Method Not Allowed) برمی گرداند.
API های توسعه یافته NextRequest و NextResponse
Next.js علاوه بر پشتیبانی از Request (opens in a new tab) و Response (opens in a new tab) معمولی، آنها را با NextRequest و NextResponse گسترش می دهد تا برای موارد استفاده پیشرفته، ابزارهای کمکی مناسبی ارائه دهد.
رفتار
کش کردن
هندلرهای مسیر به طور پیش فرض هنگام استفاده از روش GET با شی Response کش می شوند.
export async function GET() {
const res = await fetch('https://data.mongodb-api.com/...', {
headers: {
'Content-Type': 'application/json',
'API-Key': process.env.DATA_API_KEY,
},
})
const data = await res.json()
return Response.json({ data })
}هشدار تایپ اسکریپت:
Response.json()فقط از TypeScript 5.2 معتبر است. اگر از نسخه پایینتر TypeScript استفاده میکنید، میتوانید به جای آن ازNextResponse.json()برای پاسخهای دارای نوع استفاده کنید.
خارج شدن از کش
می توانید با موارد زیر از کش اجتناب کنید:
- استفاده از شیء
Requestبا روشGET. - استفاده از هر یک از روش های HTTP دیگر (غیر از GET).
- استفاده از توابع داینامیک مانند
cookiesوheaders. - گزینه های پیکربندی بخش Segment Config Options به صورت دستی حالت داینامیک را مشخص می کند.
برای مثال :
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const id = searchParams.get('id')
const res = await fetch(`https://data.mongodb-api.com/product/${id}`, {
headers: {
'Content-Type': 'application/json',
'API-Key': process.env.DATA_API_KEY!,
},
})
const product = await res.json()
return Response.json({ product })
}همانطور که مشاهده کردید، متد POST نیز باعث ارزیابی داینامیکی هندلر مسیر میشود.
export async function POST() {
const res = await fetch('https://data.mongodb-api.com/...', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'API-Key': process.env.DATA_API_KEY!,
},
body: JSON.stringify({ time: new Date().toISOString() }),
})
const data = await res.json()
return Response.json(data)
}خوب است بدانید: شبیه Route API ها، هندلرهای مسیر را میتوان برای مواردی مانند مدیریت ارسال فرم استفاده کرد. در حال حاضر روی یک انتزاع جدید برای هندل کردن فرمها و جهشها که با React یکپارچه میشود، کار میشود.
شناسایی مسیر
میتوانید یک route را ابتداییترین واحد مسیریابی در نظر بگیرید.
- آنها در طرح بندی ها (layouts) یا ناوبریهای سمت کاربر مانند صفحه (
page) شرکت نمیکنند. - در یک مسیر نمیتوان همزمان فایل
route.jsوpage.jsداشت.
| صفحه | مسیر | نتیجه |
|---|---|---|
app/page.js | app/route.js | Conflict |
app/page.js | app/api/route.js | Valid |
app/[user]/page.js | app/api/route.js | Valid |
هر فایل route.js یا page.js تمامی فعلهای HTTP را برای آن مسیر کنترل میکند.
export default function Page() {
return <h1>Hello, Next.js!</h1>
}
// ❌ Conflict
// `app/route.js`
export async function POST(request) {}مثال ها
نمونههای زیر نحوه ترکیب هندلرهای مسیر با سایر API ها و ویژگیهای Next.js را نشان میدهند.
باطلسازی مجدد دادههای کش شده
میتوانید دادههای کش شده را با استفاده از گزینه next.revalidate باطلسازی مجدد کنید: revalidate cached data
export async function GET() {
const res = await fetch('https://data.mongodb-api.com/...', {
next: { revalidate: 60 }, // Revalidate every 60 seconds
})
const data = await res.json()
return Response.json(data)
}بهعنوان جایگزین، میتوانید از گزینه پیکربندی بخش revalidate segment config option استفاده کنید:
export const revalidate = 60توابع داینامیک
هندلرهای مسیر را میتوان با توابع داینامیکی Next.js مانند cookies و headers استفاده کرد.
کوکی ها Cookies
با استفاده از cookies از next/headers میتوانید کوکیها را خوانده یا تنظیم کنید. این تابع سرور را میتوان به صورت مستقیم درون یک هندلر مسیر فراخوانی کرد یا آن را درون تابع دیگری جایگذاری کرد.
بهعنوان جایگزین، میتوانید یک Response جدید با استفاده از هدر Set-Cookie (opens in a new tab) برگردانید.
import { cookies } from 'next/headers'
export async function GET(request: Request) {
const cookieStore = cookies()
const token = cookieStore.get('token')
return new Response('Hello, Next.js!', {
status: 200,
headers: { 'Set-Cookie': `token=${token.value}` },
})
}بهعنوان جایگزین دیگری، میتوانید از APIهای وب پایهای برای خواندن کوکیها از درخواست (NextRequest) استفاده کنید.
import { type NextRequest } from 'next/server'
export async function GET(request: NextRequest) {
const token = request.cookies.get('token')
}هدرها Headers
میتوانید هدرها را با استفاده از headers از next/headers بخوانید. این تابع سرور را میتوان به صورت مستقیم درون یک هندلر مسیر فراخوانی کرد یا آن را درون تابع دیگری جایگذاری کرد.
این نمونه headers فقط برای خواندن است. برای تنظیم هدرها، نیاز است یک Response جدید با headers هدرهای جدید برگردانید.
import { headers } from 'next/headers'
export async function GET(request: Request) {
const headersList = headers()
const referer = headersList.get('referer')
return new Response('Hello, Next.js!', {
status: 200,
headers: { referer: referer },
})
}بهعنوان جایگزین دیگری، میتوانید از APIهای وب پایهای برای خواندن هدرها از درخواست (NextRequest) استفاده کنید.
import { type NextRequest } from 'next/server'
export async function GET(request: NextRequest) {
const requestHeaders = new Headers(request.headers)
}ریدایرکت ها
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
redirect('https://nextjs.org/')
}بخش های مسیر داینامیک
پیشنهاد میکنیم قبل از ادامه، صفحهی تعریف مسیرها را مطالعه کنید.
هندلرهای مسیر میتوانند از Dynamic Segments برای ایجاد مدیریت درخواستها بر اساس دادههای داینامیک استفاده کنند.
export async function GET(
request: Request,
{ params }: { params: { slug: string } }
) {
const slug = params.slug // 'a', 'b', or 'c'
}| مسیر | URL مثال | params |
|---|---|---|
app/items/[slug]/route.js | /items/a | { slug: 'a' } |
app/items/[slug]/route.js | /items/b | { slug: 'b' } |
app/items/[slug]/route.js | /items/c | { slug: 'c' } |
کوئری پارامترهای URL
شیء درخواستی (request object) که به هندلر مسیر پاس داده میشود، یک نمونه از NextRequest است که حاوی برخی متدهای راحتی اضافی برای مدیریت آسانتر پارامترهای کوئری URL میباشد.
import { type NextRequest } from 'next/server'
export function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams
const query = searchParams.get('query')
// query is "hello" for /api/search?query=hello
}استریمینگ
استریمینگ اغلب در ترکیب با مدلهای زبان بزرگ (LLMs) مانند OpenAI برای محتوای تولیدشده توسط هوش مصنوعی استفاده میشود. برای کسب اطلاعات بیشتر در مورد SDK هوش مصنوعی، اینجا AI SDK (opens in a new tab) را مطالعه کنید.
import { openai } from '@ai-sdk/openai'
import { StreamingTextResponse, streamText } from 'ai'
export async function POST(req: Request) {
const { messages } = await req.json()
const result = await streamText({
model: openai('gpt-4-turbo'),
messages,
})
return new StreamingTextResponse(result.toAIStream())
}این انتزاعیات (abstractions) از APIهای وب برای ایجاد استریم استفاده میکنند. همچنین میتوانید به صورت مستقیم از APIهای وب پایهای استفاده کنید.
// https://developer.mozilla.org/nextjs/Web/API/ReadableStream#convert_async_iterator_to_stream
function iteratorToStream(iterator: any) {
return new ReadableStream({
async pull(controller) {
const { value, done } = await iterator.next()
if (done) {
controller.close()
} else {
controller.enqueue(value)
}
},
})
}
function sleep(time: number) {
return new Promise((resolve) => {
setTimeout(resolve, time)
})
}
const encoder = new TextEncoder()
async function* makeIterator() {
yield encoder.encode('<p>One</p>')
await sleep(200)
yield encoder.encode('<p>Two</p>')
await sleep(200)
yield encoder.encode('<p>Three</p>')
}
export async function GET() {
const iterator = makeIterator()
const stream = iteratorToStream(iterator)
return new Response(stream)
}بدنه درخواست Request Body
میتوانید بدنه درخواست را با استفاده از متدهای استاندارد API وب بخوانید:
export async function POST(request: Request) {
const res = await request.json()
return Response.json({ res })
}بدنه درخواست FormData
میتوانید دادههای فرم FormData را با استفاده از تابع request.formData() بخوانید.
export async function POST(request: Request) {
const formData = await request.formData()
const name = formData.get('name')
const email = formData.get('email')
return Response.json({ name, email })
}از آنجایی که داده های formData همه رشته ها هستند، برای اعتبارسنجی و دریافت داده در قالب دلخواه (مثلا number) از zod-form-data (opens in a new tab) استفاده کنید.
CORS (Cross-origin resource sharing)
میتوانید از روشهای استاندارد API وب برای تنظیم هدرهای CORS برای یک هندلر مسیر خاص استفاده کنید :
export const dynamic = 'force-dynamic' // defaults to auto
export async function GET(request: Request) {
return new Response('Hello, Next.js!', {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
})
}خوب است بدانید:
- برای افزودن هدرهای CORS به چندین هندلر مسیر میتوانید از Middleware یا فایل
next.config.jsfile استفاده کنید.- همچنین میتوانید مثال CORS ما را در بستهی CORS example (opens in a new tab) مشاهده کنید.
وب هوک ها Webhooks
وبسرویسهای شخص ثالث میتوانند از طریق یک هندلر مسیر برای شما وبهوک ارسال کنند.
export async function POST(request: Request) {
try {
const text = await request.text()
// Process the webhook payload
} catch (error) {
return new Response(`Webhook error: ${error.message}`, {
status: 400,
})
}
return new Response('Success!', {
status: 200,
})
}قابلتوجه است که برخلاف مسیرهای API با Pages Router، برای استفاده از هندلر مسیر به هیچ پیکربندی اضافی یا استفاده از bodyParser نیاز ندارید.
پاسخهای بدون رابط کاربری Non-UI Responses
میتوانید از هندلر مسیر برای برگرداندن محتوای غیر-رابط کاربری استفاده کنید. توجه داشته باشید که sitemap.xml، robots.txt، آیکون های برنامه و تصاویر open graph همگی از پشتیبانی داخلی برخوردار هستند.
export const dynamic = 'force-dynamic' // defaults to auto
export async function GET() {
return new Response(
`<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>Next.js Documentation</title>
<link>https://nextjs.org/docs</link>
<description>The React Framework for the Web</description>
</channel>
</rss>`,
{
headers: {
'Content-Type': 'text/xml',
},
}
)
}گزینه های پیکربندی بخش
هندلرهای مسیر از همان پیکربندی بخش مسیر route segment configuration صفحات و چیدمانها استفاده میکنند.
export const dynamic = 'auto'
export const dynamicParams = true
export const revalidate = false
export const fetchCache = 'auto'
export const runtime = 'nodejs'
export const preferredRegion = 'auto'برای جزئیات بیشتر به مرجع API مراجعه کنید.