Route Handlers

Rota İşleyicileri, Web İsteği ve Yanıt API'lerini kullanarak belirli bir rota için özel istek işleyicileri oluşturmanıza olanak tanır.

Route.js Special File

Bilmekte fayda var: Rota İşleyicileri yalnızca app dizini içinde kullanılabilir. Bunlar pages dizini içindeki API Rotalarına eşdeğerdir, yani API Rotalarını ve Rota İşleyicilerini birlikte kullanmanız gerekmez.

Convention

Rota İşleyicileri app dizini içindeki bir route.js|ts dosyasında tanımlanır:

app/api/route.ts
export const dynamic = 'force-dynamic' // defaults to auto
export async function GET(request: Request) {}

Rota İşleyicileri, page.js ve layout.js dizinlerine benzer şekilde app dizini içinde yuvalanabilir. Ancak page.js ile aynı rota segmenti seviyesinde bir route.js dosyası olamaz.

Supported HTTP Methods

Aşağıdaki HTTP yöntemleri desteklenmektedir: GET, POST, PUT, PATCH, DELETE, HEAD, ve OPTIONS. Desteklenmeyen bir yöntem çağrılırsa, Next.js bir 405 Method Not Allowed yanıtı döndürür.

Extended NextRequest and NextResponse APIs

Yerel İstek ve Yanıt desteklemenin yanı sıra . Next.js bunları aşağıdakilerle genişletirNextRequest ve NextResponse gelişmiş kullanım durumları için uygun yardımcılar sağlamak.

Behavior

Caching

Response nesnesi ile GET yöntemi kullanıldığında Rota İşleyicileri varsayılan olarak önbelleğe alınır.

app/items/route.ts
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 })
}

TypeScript Uyarısı: Response.json() yalnızca TypeScript 5.2'den itibaren geçerlidir. Daha düşük bir TypeScript sürümü kullanıyorsanız NextResponse.json() bunun yerine yazılan yanıtlar için.

Opting out of caching

Önbelleğe almayı şu şekilde devre dışı bırakabilirsiniz:

Örneğin:

app/products/api/route.ts
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 })
}

Benzer şekilde, POST yöntemi de Rota İşleyicisinin dinamik olarak değerlendirilmesine neden olur.

app/items/route.ts
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)
}

Bilmekte fayda var: API Routes gibi, Route Handlers da form gönderimlerinin işlenmesi gibi durumlar için kullanılabilir. React ile derinlemesine entegre olan formları ve mutasyonları iş lemek için yeni bir soyutlama üzerinde çalışılmaktadır.

Route Resolution

Bir route adresini en düşük seviyeli yönlendirme ilkeli olarak düşünebilirsiniz.

PageRouteResult
app/page.jsapp/route.js Conflict
app/page.jsapp/api/route.js Valid
app/[user]/page.jsapp/api/route.js Valid

Her route.js veya page.js dosyası o rota için tüm HTTP fiillerini devralır.

app/page.js
export default function Page() {
  return <h1>Hello, Next.js!</h1>
}
 
// ❌ Conflict
// `app/route.js`
export async function POST(request) {}

Examples

Aşağıdaki örnekler, Route Handlers'ın diğer Next.js API'leri ve özellikleriyle nasıl birleştirileceğini göstermektedir.

Revalidating Cached Data

Önbelleğe alınmış verileri yeniden doğrulamak için next.revalidate seçenek:

app/items/route.ts
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)
}

Alternatif olarak, revalidate segment yapılandırma seçeneğini kullanabilirsiniz:

export const revalidate = 60

Dynamic Functions

Route Handlers, Next.js'deki dinamik fonksiyonlarla kullanılabilir, örneğin cookies ve headers.

Cookies

ile çerezleri okuyabilir veya ayarlayabilirsiniz. cookiesnext/headers Bu sunucu işlevi doğrudan bir Rota İşleyicide çağrılabilir veya başka bir işlevin içine yerleştirilebilir.

Alternatif olarak, yeni bir Response adresi döndürebilirsiniz. Set-Cookie Başlık.

app/api/route.ts
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}` },
  })
}

Ayrıca, çerezleri istekten okumak için temel Web API'lerini de kullanabilirsiniz (NextRequest):

app/api/route.ts
import { type NextRequest } from 'next/server'
 
export async function GET(request: NextRequest) {
  const token = request.cookies.get('token')
}

Headers

Başlıkları şu şekilde okuyabilirsiniz headersnext/headers Bu sunucu işlevi doğrudan bir Rota İşleyicide çağrılabilir veya başka bir işlevin içine yerleştirilebilir.

Bu headers örneği salt okunurdur. Başlıkları ayarlamak için, yeni headers ile yeni bir Response döndürmeniz gerekir.

app/api/route.ts
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 },
  })
}

İstekten başlıkları okumak için temel Web API'lerini de kullanabilirsiniz (NextRequest):

app/api/route.ts
import { type NextRequest } from 'next/server'
 
export async function GET(request: NextRequest) {
  const requestHeaders = new Headers(request.headers)
}

Redirects

app/api/route.ts
import { redirect } from 'next/navigation'
 
export async function GET(request: Request) {
  redirect('https://nextjs.org/')
}

Dynamic Route Segments

Devam etmeden önce Rotaların Tanımlanması sayfasını okumanızı öneririz.

Rota İşleyicileri, dinamik verilerden istek işleyicileri oluşturmak için Dinamik Segmentleri kullanabilir.

app/items/[slug]/route.ts
export async function GET(
  request: Request,
  { params }: { params: { slug: string } }
) {
  const slug = params.slug // 'a', 'b', or 'c'
}
RouteExample URLparams
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 Query Parameters

Route Handler'a aktarılan istek nesnesi, sorgu parametrelerinin daha kolay işlenmesi de dahil olmak üzere bazı ek kolaylık yöntemlerine sahip olan bir NextRequest örneğidir.

app/api/search/route.ts
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
}

Streaming

Akış, yapay zeka tarafından oluşturulan içerik için OpenAI gibi Büyük Dil Modelleri (LLM'ler) ile birlikte yaygın olarak kullanılır. AI SDK hakkında daha fazla bilgi edinin .

app/api/chat/route.ts
import OpenAI from 'openai'
import { OpenAIStream, StreamingTextResponse } from 'ai'
 
const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
})
 
export const runtime = 'edge'
 
export async function POST(req: Request) {
  const { messages } = await req.json()
  const response = await openai.chat.completions.create({
    model: 'gpt-3.5-turbo',
    stream: true,
    messages,
  })
 
  const stream = OpenAIStream(response)
 
  return new StreamingTextResponse(stream)
}

Bu soyutlamalar bir akış oluşturmak için Web API'lerini kullanır. Temel Web API'lerini doğrudan da kullanabilirsiniz.

app/api/route.ts
// https://developer.mozilla.org/docs/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

Standart Web API yöntemlerini kullanarak Request gövdesini okuyabilirsiniz:

app/items/route.ts
export async function POST(request: Request) {
  const res = await request.json()
  return Response.json({ res })
}

Request Body FormData

request.formData() işlevini kullanarak FormData adresini okuyabilirsiniz:

app/items/route.ts
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 verilerinin tümü dizeler olduğundan, şunları kullanmak isteyebilirsiniz zod-form-data isteği doğrulamak ve verileri tercih ettiğiniz biçimde almak için (örn. number).

CORS

Standart Web API yöntemlerini kullanarak Response adresinde CORS başlıklarını ayarlayabilirsiniz:

app/api/route.ts
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',
    },
  })
}

Webhooks

Üçüncü taraf hizmetlerden web kancaları almak için bir Rota İşleyicisi kullanabilirsiniz:

app/api/route.ts
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,
  })
}

Özellikle, Pages Router ile API Routes'ın aksine, herhangi bir ek yapılandırma kullanmak için bodyParser adresini kullanmanız gerekmez.

Edge and Node.js Runtimes

Route Handlers, akış desteği de dahil olmak üzere hem Edge hem de Node.js çalışma zamanlarını sorunsuz bir şekilde desteklemek için izomorfik bir Web API'sine sahiptir. Rota İşleyicileri, Sayfalar ve Düzenlerle aynı rota segmenti yapılandırmasını kullandığından, genel amaçlı statik olarak yeniden oluşturulan Rota İşleyicileri gibi uzun zamandır beklenen özellikleri destekler.

Çalışma zamanını belirtmek için runtime segment config seçeneğini kullanabilirsiniz:

export const runtime = 'edge' // 'nodejs' is the default

Non-UI Responses

UI olmayan içeriği döndürmek için Rota İşleyicileri kullanabilirsiniz. Şuna dikkat edin sitemap.xml, robots.txt, app iconsve açık grafik görüntülerinin tümü yerleşik desteğe sahiptir.

app/rss.xml/route.ts
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',
      },
    }
  )
}

Segment Config Options

Rota İşleyicileri, sayfalar ve düzenlerle aynı rota segmenti yapılandırmasını kullanır.

app/items/route.ts
export const dynamic = 'auto'
export const dynamicParams = true
export const revalidate = false
export const fetchCache = 'auto'
export const runtime = 'nodejs'
export const preferredRegion = 'auto'

Daha fazla ayrıntı için API referansına bakın.