Next.js Route Handlers (API 路由)
Route Handlers 是 Next.js App Router 中用來建立 Web API 的機制。它們允許你針對特定的路由定義 HTTP 方法(如 GET, POST 等),並回傳自定義的 Response。
這是在 Next.js 中建立後端邏輯的標準方式,取代了過去 Pages Router 的 pages/api。
適用場景 (When to use?)
- 公開 API (Public API):提供 JSON 資料給行動裝置 App 或第三方開發者。
- Webhooks:接收外部服務(如 Stripe 還有 LINE Bot)的事件通知。
- 非 JSON 回應:需要動態生成 RSS Feed、圖片或
sitemap.xml。 - 代理請求 (Proxying):隱藏 API Key,由 Server 端轉發請求給第三方服務。
定義路由 (Basic Usage)
Route Handlers 定義在 app 目錄下的 route.ts (或 .js) 檔案中。
檔案結構範例:
app/api/users/route.ts-> URL:/api/usersapp/auth/callback/route.ts-> URL:/auth/callback
基礎語法
你需要匯出與 HTTP 方法同名的 async 函式:
// app/api/hello/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({ message: 'Hello World' });
}
export async function POST(request: Request) {
const body = await request.json();
return NextResponse.json({ received: body });
}
支援的方法:GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS。
處理請求 (Request Object)
Next.js 擴充了標準 Web Request API,提供了 NextRequest 物件,讓你更容易讀取 URL 參數、Cookies 和 Headers。
讀取 URL 參數 (Query Parameters)
常見誤區:Route Handlers 不像 Page props 那樣直接從參數拿 query,而是要從 request.nextUrl 解析。
import { type NextRequest, NextResponse } from 'next/server';
export function GET(request: NextRequest) {
// 取得 /api/search?q=nextjs 中的 q
const searchParams = request.nextUrl.searchParams;
const query = searchParams.get('q');
return NextResponse.json({ query });
}
讀取 Body 資料
export async function POST(request: NextRequest) {
// 1. 讀取 JSON
const json = await request.json();
// 2. 讀取 FormData (例如上傳檔案)
// const formData = await request.formData();
// 3. 讀取純文字 (例如 Webhook 簽章驗證)
// const text = await request.text();
return NextResponse.json({ status: 'ok' });
}
讀取 Cookies 與 Headers
import { cookies, headers } from 'next/headers'; // 推薦使用 helper functions
export async function GET(request: NextRequest) {
// 方法 A: 從 request 物件讀取 (唯讀)
const userAgent = request.headers.get('user-agent');
// 方法 B: 使用 next/headers helper (更方便)
const cookieStore = cookies();
const token = cookieStore.get('token');
const headersList = headers();
const referer = headersList.get('referer');
return NextResponse.json({ userAgent, hasToken: !!token });
}
動態路由參數 (Dynamic Route Segments)
就像 Page 一樣,Route Handlers 也可以透過資料夾名稱 [slug] 來擷取路徑參數。這些參數會作為第二個引數傳入函式。
路徑:app/api/products/[id]/route.ts
export async function GET(request: NextRequest, { params }: { params: { id: string } }) {
const productId = params.id;
return NextResponse.json({
id: productId,
name: `Product ${productId}`,
});
}
回應處理 (Response)
回傳 JSON
return NextResponse.json({ data: 'Foo' }, { status: 200 });
轉址 (Redirect)
import { redirect } from 'next/navigation';
export async function GET(request: NextRequest) {
redirect('https://google.com'); // 拋出 error 中斷執行並轉址
}
串流回應 (Streaming)
這對於生成 AI 回應或大量資料傳輸非常有用。
// app/api/stream/route.ts
export async function GET() {
const stream = new ReadableStream({
async start(controller) {
const encoder = new TextEncoder();
// 模擬逐步傳送資料
for (let i = 0; i < 5; i++) {
await new Promise((r) => setTimeout(r, 500));
controller.enqueue(encoder.encode(`Chunk ${i}\n`));
}
controller.close();
},
});
return new Response(stream, {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
}
快取行為 (Caching)
這是最容易讓人困惑的地方。Next.js 的 GET Route Handlers 預設會有不同的快取行為:
- 預設快取 (Static):如果
GET方法沒有使用Request物件,也沒有使用動態函式 (cookies, headers),Next.js 會在 build time 靜態生成結果並快取。 - 動態執行 (Dynamic):如果用了
Request物件、cookies()或是在開發模式,則會變成動態渲染。
若要強制指定行為,可以使用 Route Segment Config:
// 強制為動態 (Dynamic),每次請求都重新執行
export const dynamic = 'force-dynamic';
// 或者設定 Revalidation 時間 (ISR)
// export const revalidate = 60; // 每 60 秒更新一次
CORS (跨域資源共享)
如果你的 API 需要被其他網域的前端呼叫,你需要處理 CORS 預檢請求 (Preflight)。
// app/api/cors/route.ts
export async function OPTIONS() {
return new Response(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}
export async function GET() {
return NextResponse.json(
{ data: 'Public Data' },
{
headers: { 'Access-Control-Allow-Origin': '*' },
}
);
}
小結
Route Handlers 為 Next.js 提供了完整的後端開發能力。
- 使用
app/api/.../route.ts定義。 - 透過
NextRequest讀取searchParams和body。 - 支援標準 Web API (
Response,ReadableStream)。 - 留意
GET的預設快取行為,必要時使用export const dynamic = 'force-dynamic'。
掌握了 Route Handlers,你就能在 Next.js 專案中輕鬆構建全功能的 RESTful API 或 Webhook 處理器。