Next.js API路由基础 #
一、API路由概述 #
1.1 什么是API路由 #
API路由允许在Next.js应用中创建API端点:
text
app/
└── api/
└── hello/
└── route.ts → /api/hello
1.2 创建API路由 #
tsx
import { NextResponse } from 'next/server'
export async function GET() {
return NextResponse.json({ message: 'Hello World' })
}
1.3 HTTP方法 #
| 方法 | 函数名 | 说明 |
|---|---|---|
| GET | GET() | 获取资源 |
| POST | POST() | 创建资源 |
| PUT | PUT() | 更新资源 |
| PATCH | PATCH() | 部分更新 |
| DELETE | DELETE() | 删除资源 |
| HEAD | HEAD() | 获取头信息 |
| OPTIONS | OPTIONS() | 获取支持的方法 |
二、请求处理 #
2.1 请求对象 #
tsx
import { NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const url = request.url
const method = request.method
const headers = request.headers
const cookies = request.cookies
const searchParams = request.nextUrl.searchParams
const query = searchParams.get('q')
return NextResponse.json({ url, method, query })
}
2.2 读取请求体 #
tsx
import { NextRequest, NextResponse } from 'next/server'
export async function POST(request: NextRequest) {
const body = await request.json()
return NextResponse.json({ received: body })
}
2.3 读取表单数据 #
tsx
import { NextRequest, NextResponse } from 'next/server'
export async function POST(request: NextRequest) {
const formData = await request.formData()
const name = formData.get('name')
const file = formData.get('file') as File
return NextResponse.json({ name, filename: file?.name })
}
2.4 读取Cookie #
tsx
import { NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const token = request.cookies.get('token')
return NextResponse.json({ token: token?.value })
}
2.5 读取Header #
tsx
import { NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const authorization = request.headers.get('authorization')
const userAgent = request.headers.get('user-agent')
return NextResponse.json({ authorization, userAgent })
}
三、响应处理 #
3.1 JSON响应 #
tsx
import { NextResponse } from 'next/server'
export async function GET() {
return NextResponse.json(
{ message: 'Success', data: { id: 1, name: 'Test' } },
{ status: 200 }
)
}
3.2 自定义响应 #
tsx
import { NextResponse } from 'next/server'
export async function GET() {
return new NextResponse('Hello World', {
status: 200,
headers: {
'Content-Type': 'text/plain',
'X-Custom-Header': 'value',
},
})
}
3.3 设置Cookie #
tsx
import { NextResponse } from 'next/server'
export async function POST() {
const response = NextResponse.json({ success: true })
response.cookies.set('token', 'jwt-token', {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 60 * 60 * 24 * 7,
})
return response
}
3.4 设置Header #
tsx
import { NextResponse } from 'next/server'
export async function GET() {
const response = NextResponse.json({ data: 'test' })
response.headers.set('X-Custom-Header', 'value')
response.headers.set('Cache-Control', 'public, max-age=3600')
return response
}
3.5 重定向 #
tsx
import { NextResponse } from 'next/server'
export async function GET() {
return NextResponse.redirect(new URL('/login', 'https://example.com'))
}
四、动态路由 #
4.1 动态参数 #
tsx
interface RouteContext {
params: Promise<{ id: string }>
}
export async function GET(request: Request, { params }: RouteContext) {
const { id } = await params
return NextResponse.json({ id })
}
4.2 捕获所有路由 #
tsx
interface RouteContext {
params: Promise<{ slug: string[] }>
}
export async function GET(request: Request, { params }: RouteContext) {
const { slug } = await params
return NextResponse.json({ path: slug.join('/') })
}
五、错误处理 #
5.1 错误响应 #
tsx
import { NextResponse } from 'next/server'
export async function GET() {
try {
const data = await getData()
return NextResponse.json(data)
} catch (error) {
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
)
}
}
5.2 验证错误 #
tsx
import { NextResponse } from 'next/server'
import { z } from 'zod'
const schema = z.object({
name: z.string().min(1),
email: z.string().email(),
})
export async function POST(request: Request) {
const body = await request.json()
const result = schema.safeParse(body)
if (!result.success) {
return NextResponse.json(
{ error: 'Validation Error', details: result.error.flatten() },
{ status: 400 }
)
}
return NextResponse.json({ success: true, data: result.data })
}
六、中间件 #
6.1 CORS #
tsx
import { NextResponse } from 'next/server'
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}
export async function OPTIONS() {
return NextResponse.json({}, { headers: corsHeaders })
}
export async function GET() {
return NextResponse.json(
{ data: 'test' },
{ headers: corsHeaders }
)
}
6.2 认证 #
tsx
import { NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const token = request.headers.get('authorization')?.replace('Bearer ', '')
if (!token) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
)
}
const user = await verifyToken(token)
if (!user) {
return NextResponse.json(
{ error: 'Invalid token' },
{ status: 401 }
)
}
return NextResponse.json({ user })
}
七、最佳实践 #
7.1 类型安全 #
tsx
interface User {
id: string
name: string
email: string
}
interface ApiResponse<T> {
data: T
message: string
}
export async function GET(): Promise<NextResponse<ApiResponse<User>>> {
const user = await getUser()
return NextResponse.json({
data: user,
message: 'Success',
})
}
7.2 错误处理封装 #
tsx
import { NextResponse } from 'next/server'
class ApiError extends Error {
constructor(public message: string, public status: number) {
super(message)
}
}
export function handleError(error: unknown) {
if (error instanceof ApiError) {
return NextResponse.json(
{ error: error.message },
{ status: error.status }
)
}
console.error('API Error:', error)
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
)
}
八、总结 #
API路由基础要点:
| 要点 | 说明 |
|---|---|
| 路由文件 | route.ts |
| HTTP方法 | GET/POST/PUT/DELETE |
| 请求对象 | NextRequest |
| 响应对象 | NextResponse |
| 动态路由 | [id]/route.ts |
| 错误处理 | try/catch |
下一步,让我们学习Route Handlers!
最后更新:2026-03-28