Next.js API Router

posted on: 2025/08/29 10:23
はじめに
Next.js(Next.js 13 以降の App Router)のAPI Routerについてまとめておきます。
以前学習のためにExpressで簡単なバックエンドを実装したことがありますが、Next.jsの方が便利だと実感しました。
Next.js APIルーター解説
1. 基本概念
Next.jsのAPI Routerは、Next.jsプロジェクト内でバックエンドAPIを作成するための仕組みです。
- Expressのような別個のサーバーを用意する必要がなく、フロントエンドと同じプロジェクト内で開発が完結します。
- App Routerを使用する場合、
app/apiフォルダ配下にファイルを作成すると、自動的にエンドポイントとして機能します。
2. ディレクトリ構造とURL
App RouterでのAPIエンドポイントの定義は以下のようになります:
app/└─ api/└─ hello/└─ route.ts
- この場合のURLは
/api/helloとなります。 - App Routerでは、APIエンドポイントのファイル名は**
route.tsに固定**されています。
3. ハンドラーの記述方法(メソッドごと)
ハンドラーはapp/api/hello/route.tsのようなファイルに記述します。
NextRequestとNextResponseオブジェクトを使用します。- HTTPメソッド(GET, POSTなど)ごとに独立した関数を定義します。
- Expressのように
req.methodを使ってメソッドを分岐させる必要がありません。
例:
// app/api/hello/route.ts
import { NextRequest, NextResponse } from 'next/server'
// GET メソッドのハンドラー
export async function GET(req: NextRequest) {
return NextResponse.json({ message: 'Hello from GET' }) // JSON形式でレスポンスを返す
}
// POST メソッドのハンドラー
export async function POST(req: NextRequest) {
const data = await req.json() // リクエストボディからJSONデータを取得
return NextResponse.json({ received: data }) // 受信したデータをJSON形式で返す
}
4. 特徴・メリット
Next.js API Routerには以下の特徴とメリットがあります:
- 統合型: フロントエンドと同じNext.jsプロジェクト内でAPIを管理できます。
- 自動ルーティング: ファイルを所定の場所に置くだけで、自動的にURLが生成されます。
- 型安全: TypeScriptを利用することで、
NextRequestやNextResponseに型安全が適用されます。 - SSR/フロント連携: フロントエンドから
fetch('/api/xxx')のように簡単にAPIを呼び出すことが可能です。 - デプロイ簡単: VercelやNetlifyなどのプラットフォームにそのままデプロイできます。
5. 例:簡単なCRUD API (Todoリスト)
Todoリストの簡単なCRUD APIをapp/api/todos/route.tsで実装する例です。
// app/api/todos/route.ts
import { NextRequest, NextResponse } from 'next/server'
let todos: string[] = [] // 仮のデータストア
// GET メソッド:現在のTodoリストを取得
export async function GET() {
return NextResponse.json({ todos }) // todos配列をJSONで返す
}
// POST メソッド:新しいTodoを追加
export async function POST(req: NextRequest) {
const { todo } = await req.json() // リクエストボディから新しいtodoを取得
todos.push(todo) // todos配列に追加
return NextResponse.json({ todos }) // 更新されたtodos配列をJSONで返す
}
GET /api/todos→ 現在のTodoリストを取得します。POST /api/todos→ 新しいTodo項目を追加します。
6. APIの呼び出し方(フロントエンドから)
Next.js 13のApp Routerで作成したAPI Routesは、Reactコンポーネント(特にクライアントコンポーネント)から簡単に呼び出すことができます。
6.1. Reactコンポーネント(Client Component)での呼び出し例
以下の例は、/api/todosエンドポイントを呼び出してTodoリストを取得・追加するクライアントコンポーネントです。
// Client Component
'use client' // クライアントコンポーネントであることを明示
import { useState, useEffect } from 'react'
export default function TodoApp() {
const [todos, setTodos] = useState<string[]>([])
const [input, setInput] = useState('')
// GETメソッドで初期データを取得
useEffect(() => {
fetch('/api/todos') // /api/todos を呼び出す
.then(res => res.json())
.then(data => setTodos(data.todos))
}, [])
// POSTメソッドで新しいTodoを追加
const addTodo = async () => {
const res = await fetch('/api/todos', { // /api/todos にPOSTリクエストを送信
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ todo: input }) // リクエストボディにJSONデータを設定
})
const data = await res.json()
setTodos(data.todos)
setInput('')
}
return (
<>
<ul>
{todos.map((t, i) => <li key={i}>{t}</li>)}
</ul>
<input
value={input}
onChange={e => setInput(e.target.value)}
placeholder="New Todo"
/>
<button onClick={addTodo}>Add</button>
</>
)
}
6.2. 呼び出しのポイント
fetch('/api/todos')で API Routes を呼べる: URLはプロジェクトルートからの相対パスでOKです。- メソッドごとの呼び分け:
- GET → 初期データ取得に使用されます。
- POST → データ送信に使用されます。
- Client Component でのみ呼ぶ:
use clientを付けることで、クライアントサイドでfetchが利用可能になります。 - 型安全: TypeScriptで型を定義することで、
fetchのレスポンスも型チェックできます。
6.3. 型安全にする例
APIからのレスポンスの型を定義することで、より安全にデータを扱えます。
type TodosResponse = { todos: string[] } // レスポンスの型を定義
// useEffect内で型アサーションを使用
useEffect(() => {
fetch('/api/todos')
.then(res => res.json() as Promise<TodosResponse>) // Promise<TodosResponse>として型アサーション
.then(data => setTodos(data.todos))
}, [])
まとめ
- Next.js 13のApp RouterにおけるAPI Routesは、フロントエンドと統合されたバックエンドAPIを構築する機能です。
app/api/<path>/route.tsにファイルを配置することで、自動的にエンドポイントが生成されます。- HTTPメソッドごとに関数を定義する方式を採用しており、Expressのような複雑なルーティング設定は不要です。
- 作成したAPIは、フロントエンドのクライアントコンポーネントから
fetchを使って簡単に呼び出すことができます。 - 相対パスでのURL指定や、型安全な実装が可能です。
