Next.js Route Handlers
Next.jsはReactベースのフレームワークですが、Route Handlersという機能を利用することで、サーバーサイドのAPIエンドポイントを簡単に作成できます。この仕組みによって、Next.jsアプリ内でAPIをサーバーレスで定義できます。
Next.js 13以降の App Router を使用します。従来の「API Routes」(Page Router用)とは異なる方法です。
Route Handlers
Next.jsの Route Handlers は、app/api
ディレクトリ内にファイルを配置することで、サーバーレスなAPIエンドポイントを簡単に作成できます。例えば、app/api/book/route.js
というファイルを作成すると、/api/book
というエンドポイントが自動的に作成されます。
フォルダ構成
Next.jsのapp
ディレクトリを使用する場合、APIルートや動的ルートは以下のように構成できます。
your-nextjs-project/
├── app/
│ ├── api/ # APIエンドポイント用
│ │ ├── book/ # /api/book エンドポイント
│ │ │ └── route.js # /api/book のハンドラー
│ │ └── book/ # 動的APIルート用
│ │ └── [id]/ # /api/book/[id] 動的エンドポイント
│ │ └── route.js # 動的ハンドラー
│ ├── book/ # ページ用
│ │ ├── page.js # /book ページ(書籍リスト)
│ │ └── [id]/ # /book/[id] 動的ページ(書籍詳細)
│ │ └── page.js
例:app/api/book/route.js
// app/api/book/route.js
export async function GET() {
return Response.json([{ id: 1, title: "よくわかるNext.js" }]);
}
export async function POST(req) {
const { title } = await req.json();
return Response.json({ id: 2, title }, { status: 201 });
}
このコードでは、GET
メソッドで書籍リストを返し、POST
メソッドで新しい書籍のタイトルを受け取って、それを基に新しい書籍を作成します。
例:app/api/book/[id]/route.js
// app/api/book/[id]/route.js
export async function GET(req, { params }) {
const { id } = params;
return Response.json({ id, title: `Book ${id}` });
}
このコードでは、[id]
という動的パラメータを受け取って、該当する書籍の情報を返します。例えば、/api/book/123
にアクセスすると、{ id: 123, title: 'Book 123' }
というレスポンスが返されます。
フロントエンド:書籍リストを表示する
フロントエンド側で、バックエンドのAPIから書籍リストを取得して表示できます。
1. 書籍リストを表示するフロントエンド(app/book/page.js
)
async function fetchBooks() {
const response = await fetch("/api/book", { cache: "no-store" });
return response.json();
}
export default async function BookList() {
const books = await fetchBooks();
return (
<div>
<h1>Book List</h1>
<ul>
{books.map((book) => (
<li key={book.id}>{book.title}</li>
))}
</ul>
</div>
);
}
-
fetch
:/api/book
というエンドポイントにGETリクエストを送り、書籍リストを取得します。 -
cache: "no-store"
: App Routerではデフォルトでキャッシュされるため、最新データを確実に取得するために追加。 -
map
: 取得した書籍データをリストとして表示します。
2. 動的ルートの書籍詳細ページ(app/book/[id]/page.js
)
async function fetchBook(id) {
const response = await fetch(`/api/book/${id}`, { cache: "no-store" });
return response.json();
}
export default async function BookDetail({ params }) {
const { id } = params;
const book = await fetchBook(id);
return (
<div>
<h1>Book Detail</h1>
<div>
<p>書籍ID: {book.id}</p>
<p>タイトル: {book.title}</p>
</div>
</div>
);
}
-
動的ルーティング:
params
からid
を取得し、そのIDに基づいて書籍詳細を表示します。 -
fetch
:/api/book/[id]
エンドポイントにGETリクエストを送り、書籍の詳細情報を取得します。
まとめ
Route Handlersを使用することで、app
ディレクトリ内でサーバーレスなAPIを簡単に構築でき、Reactアプリケーション内で直接APIを呼び出すことが可能です。
実際に使用する際には、外部APIやデータベースと連携して、より多様なデータソースから情報を取得することも可能です。
たとえば、/api/book
や/api/book/[id]
のエンドポイントを外部APIに置き換えることで、リアルタイムのデータや外部サービスとの連携を容易に行えます。