API Routes (Route Handlers) в Next.js
Route Handlers (в Pages Router назывались API Routes) позволяют создавать серверные API-эндпоинты прямо в Next.js приложении. Они определяются в файлах route.ts внутри директории app.
Базовый пример
// app/api/problems/route.ts
import { NextResponse } from 'next/server'
import { db } from '@/lib/db'
export async function GET() {
const problems = await db.problem.findMany()
return NextResponse.json(problems)
}
export async function POST(request: Request) {
const body = await request.json()
const problem = await db.problem.create({
data: body
})
return NextResponse.json(problem, { status: 201 })
}
Каждый экспортированный метод (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) обрабатывает соответствующий HTTP-запрос.
Динамические Route Handlers
// app/api/problems/[id]/route.ts
import { NextResponse } from 'next/server'
import { db } from '@/lib/db'
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
const problem = await db.problem.findUnique({
where: { id: params.id }
})
if (!problem) {
return NextResponse.json(
{ error: 'Problem not found' },
{ status: 404 }
)
}
return NextResponse.json(problem)
}
export async function DELETE(
request: Request,
{ params }: { params: { id: string } }
) {
await db.problem.delete({ where: { id: params.id } })
return new Response(null, { status: 204 })
}
Работа с Request
Route Handlers используют стандартный Web API Request:
// app/api/search/route.ts
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const query = searchParams.get('q')
if (!query) {
return NextResponse.json(
{ error: 'Query parameter required' },
{ status: 400 }
)
}
const results = await db.problem.findMany({
where: { name: { contains: query, mode: 'insensitive' } }
})
return NextResponse.json(results)
}
Чтение заголовков и cookies
import { cookies, headers } from 'next/headers'
export async function GET() {
const cookieStore = cookies()
const token = cookieStore.get('session')
const headersList = headers()
const userAgent = headersList.get('user-agent')
return NextResponse.json({ token, userAgent })
}
Кеширование
GET-запросы без чтения Request кешируются по умолчанию:
// Кешируется (статический Route Handler)
export async function GET() {
const data = await fetch('https://api.example.com/data')
return NextResponse.json(data)
}
// Не кешируется (читаем Request)
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
// ...
}
Для явного управления кешем:
export const dynamic = 'force-dynamic' // всегда динамический
export const revalidate = 300 // ревалидация через 5 минут
Route Handlers vs Server Actions
| Route Handlers | Server Actions | |
|---|---|---|
| Назначение | API-эндпоинты | Мутации из UI |
| HTTP-методы | GET, POST, PUT, DELETE... | Только POST |
| Вызов из | Любой клиент (fetch, curl) | Только из компонентов |
| Progressive enhancement | Нет | Да (формы) |
Когда что использовать:
Используй Server Actions для мутаций данных из интерфейса (формы, кнопки). Используй Route Handlers для публичных API, webhook'ов, интеграций с внешними сервисами и случаев, когда нужны конкретные HTTP-методы.
Полезные ресурсы
- nextjs.org/docs — Route Handlers
- route.ts API Reference