Next.js APIルート:Route Handlerの実装例
Next.js Route Handlerの実装例
Next.js APIルート(Route Handler):GET、POST、認証 | We.Inc
App Router向けのNext.js Route Handlerの実装例集。クエリパラメーター付きのGET、バリデーション付きのPOST、Promiseとして渡される動的パラメーター、認証チェック、CORS、Webhookをコピーして使えます。
App Routerでは、APIエンドポイントはappの中に置くroute.tsファイルです。例:app/api/todos/route.ts。GETやPOSTなどHTTPメソッド名の非同期関数をエクスポートします。各関数はRequestを受け取ってResponseを返し、通常はResponse.json()を使います。動的セグメントはプロミスとして渡されるので、待機して値を取り出します。Next.js 15以降、GETハンドラーはデフォルトで動的です。
Route Handlerの基本
- JSONを返す
- return Response.json(data, { status: 200 })
- JSONボディを読む
- const body = await request.json()
- フォームデータを読む
- const form = await request.formData()
- ?q=を読む
- request.nextUrl.searchParams.get("q")
- 動的セグメント
- const { id } = await params
- Cookieとヘッダー
- await cookies(), await headers() from next/headers
Pages RouterのAPIルートはreqとresオブジェクトを使っていました。一方Route Handlerは、標準のWeb RequestとResponseを使います。古い回答をそのままコピーすると、ここでつまずきがちです。以下では、実際のアプリで必要になるパターンを、すべて現行のApp Router向けに紹介します。さらに、バリデーションを行うPOSTが返すべきステータスコードを確認できる小さなテスターも用意しています。
- テスターに架空のリクエストボディを入力し、呼び出し元がサインインしているかどうかを選びます。
- テスターは、このページのPOSTの例と同じバリデーションルールをブラウザー内で実行します。
- 返ってきたステータスコードとJSONを確認し、項目を変えて400、401、201になる様子を見てみましょう。
- 例のハンドラーをコピーし、メモリー上のリストを自分のデータベースに置き換えます。
- すべてのハンドラーを公開エンドポイントとして扱いましょう。プロキシがすでに未サインインのユーザーをリダイレクトしていても、ハンドラーの中でセッションを確認してください。
- Zodなどのスキーマライブラリでボディを検証し、不正なデータで500エラーを起こすのではなく、項目ごとのエラーとともに400を返しましょう。
- route.tsファイルはpage.tsxと同じフォルダーには置けません。APIはapp/apiの下にまとめて分けておきましょう。
- OPTIONSをエクスポートしていない場合、Next.jsがエクスポート済みのメソッドを列挙したAllowヘッダーで自動的に応答します。
- Webhookでは、署名の検証に正確なバイト列が必要なため、パースする前にrequest.text()で生のボディを読み取りましょう。
よくある質問
Next.jsのAPIルートは非推奨になったのですか?
Pages Routerではpages/apiのルートが引き続き動作します。App Routerでそれに相当するのがRoute Handlerで、Web RequestとResponseオブジェクトを使うroute.tsファイルです。bodyParserの設定は不要です。
route.tsはどのHTTPメソッドをエクスポートできますか?
GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONSです。エクスポートしていないメソッドを呼び出すと、405 Method Not Allowedが返ります。
なぜparamsをawaitする必要があるのですか?
Next.js 15以降、コンテキスト引数のparamsはプロミスになりました。const { id } = await paramsと書きます。next dev、next build、next typegenで生成されるRouteContextヘルパー型を使えば、ルートのパスから型付きのparamsが得られます。
GETのRoute Handlerはキャッシュされますか?
現在はデフォルトではキャッシュされません。Next.js 15でGETハンドラーは静的から動的に変更されました。キャッシュを再び有効にするには、export const dynamic = 'force-static'かrevalidateの値を指定します。Cache Componentsを有効にしている場合は、use cacheをハンドラー本体ではなく、ハンドラーが呼び出すヘルパー関数の中に書きます。
Route HandlerとServer Actionのどちらを使うべきですか?
自分のフォームやボタンから実行するデータ変更にはServer Actionを使います。モバイルアプリ、Webhook、cronジョブ、外部のスクリプトなど、Reactのツリーの外からURLを呼び出す場合はRoute Handlerを使います。
ファイル構成
- フォルダーのパスがそのままURLになります。app/api/todos/route.tsは/api/todosに、app/api/todos/[id]/route.tsは/api/todos/42に応答します。[...slug]のようなキャッチオールフォルダーでは、セグメントの配列が渡されます。
- Route Handlerはページとセグメント設定を共有するため、同じdynamic、revalidate、runtimeのエクスポートがそのまま適用されます。
クライアントが理解できるステータスコード
- 何かを作成したら201、入力が誤っていれば400、誰もサインインしていなければ401、サインイン中のユーザーに権限がなければ403、レコードが存在しなければ404、未対応のメソッドには405を返します。そうすればフロントエンドはエラー文を解析せずに、コードで処理を分岐できます。
- エラーには{ error: string, fields?: object }のような一貫したJSONの形を返し、1つの取得用ヘルパーですべて処理できるようにしましょう。
セキュリティのチェックリスト
- セッションを検証し、変更しようとしているレコードがそのユーザーのものかを確認し、データを検証し、秘密情報やユーザー行全体をそのまま返さないようにしましょう。公式の認証ガイドでは、セッションがなければ401、権限が違えば403という2段階のパターンが示されています。
- CORSヘッダーは、他のオリジンから本当に呼び出す必要があるハンドラーにだけ設定しましょう。Cookieが関わる場合は、アスタリスクではなく特定のオリジンを列挙してください。
Route Handlerの実装例
検索クエリ付きのGET
app/api/todos/route.ts。qパラメーターでリストを絞り込み、クエリが空ならすべてを返します。
Zodによるバリデーションと認証チェック付きのPOST
セッションがなければ401、ボディが不正なら項目ごとのエラーとともに400、それ以外は新しいレコードとともに201を返します。getSessionは、お使いの認証ライブラリの代わりとして置いています。
paramsをawaitする動的セグメント
app/api/todos/[id]/route.ts。Next.js 15以降、paramsはPromiseです。
信頼できる1つのオリジン向けのCORS
ブラウザーのプリフライトと実際のリクエストの両方に、同じ許可オリジンで応答します。
Client Componentからハンドラーを呼び出す
fetchヘルパーが最初にステータスコードを読むので、フォームは400の項目別エラーを表示できます。
Pages RouterのAPIルートとRoute Handlerの比較
同じ処理、異なるAPI
- pages/api/x.ts
- app/api/x/route.ts
- ハンドラー
- export default function handler(req, res)
- export async function GET(request)
- JSONを送る
- res.status(200).json(data)
- return Response.json(data)
- メソッドの分岐
- if (req.method === "POST")
- POST関数を個別にエクスポート
- ボディの解析
- req.body(bodyParserの設定)
- await request.json()またはrequest.formData()
- クエリ文字列
- request.nextUrl.searchParams
POSTテスター
JSONボディを編集し、呼び出し元がサインインしているかを選ぶと、バリデーションを行うPOSTの例が返すステータスコードとレスポンスを確認できます。
メソッド
リクエストボディ(JSON)
呼び出し元に有効なセッションがある
レスポンス
PUTでは、ファイルがエクスポートしていないメソッドに対してNext.jsが返す405を確認できます。
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る