# 機能設計書 30-API Routes

## 概要

本ドキュメントは、Next.js Pages RouterにおけるAPI Routes機能の設計を記述する。API Routesは、`pages/api/`ディレクトリ配下のファイルによるAPIエンドポイントの定義機能であり、Node.jsのreq/resインターフェースを使用してHTTPリクエストを処理する。

### 本機能の処理概要

**業務上の目的・背景**：フルスタックWebアプリケーションでは、バックエンドAPIが必要である。API Routesは、Next.jsプロジェクト内にサーバーサイドのAPIエンドポイントを定義する仕組みを提供し、別途バックエンドサーバーを構築することなくAPIを構築できる。Node.jsのIncomingMessage/ServerResponseをベースとした使い慣れたAPIで、Express/Koa等のミドルウェアパターンとの互換性も高い。

**機能の利用シーン**：フォーム送信の処理、データベースCRUD操作、外部APIとのプロキシ、認証エンドポイント、Webhookの受信、ファイルアップロード、プレビューモードの切り替えなど。

**主要な処理内容**：
1. `pages/api/`ディレクトリ配下のファイルからAPIエンドポイントを自動生成
2. Node.jsのIncomingMessage/ServerResponseをNextApiRequest/NextApiResponseに拡張
3. リクエストボディのパース（JSON/URLEncoded/Multipart）
4. ヘルパーメソッドの提供（res.json()、res.status()、res.redirect()等）
5. API Configによるボディパーサー設定やレスポンスサイズ制限

**関連システム・外部連携**：Node.jsランタイム、Pages Routerのルーティングシステム、プレビューモード（Draft Mode）、revalidateAPIと連携する。

**権限による制御**：ハンドラ関数内でreq.cookies/req.headersを用いた認証チェックを独自に実装可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | API RoutesはAPIエンドポイントであり、直接的な画面はない |

## 機能種別

API処理 / CRUD操作 / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| req | NextApiRequest | Yes | 拡張HTTPリクエストオブジェクト | IncomingMessageの拡張 |
| res | NextApiResponse | Yes | 拡張HTTPレスポンスオブジェクト | ServerResponseの拡張 |
| req.query | ParsedUrlQuery | Yes | URLクエリパラメータ | オブジェクト形式 |
| req.body | any | No | パース済みリクエストボディ | bodyParser有効時 |
| req.cookies | NextApiRequestCookies | Yes | リクエストCookie | オブジェクト形式 |

### 入力データソース

- HTTPリクエスト（クライアントからのAPI呼び出し）
- 動的ルートパラメータ（`pages/api/[id].ts`等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| status | number | HTTPステータスコード |
| body | any | レスポンスボディ（JSON/テキスト/ストリーム/Buffer） |
| headers | Record<string, string> | レスポンスヘッダー |

### 出力先

- HTTPレスポンスとしてクライアントに送信

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ pages/api/以下のルートにマッチするリクエストを検出
2. PagesAPIRouteModule.render
   └─ apiResolverWrappedに処理を委譲
3. リクエスト前処理
   └─ Cookie解析、ボディパース、プレビューモード判定
4. NextApiRequest/NextApiResponse構築
   └─ ヘルパーメソッド(json/status/redirect等)の注入
5. ユーザーハンドラ実行
   └─ デフォルトエクスポートされたハンドラ関数を実行
6. レスポンス処理
   └─ ETag生成、レスポンスサイズ検証、送信
```

### フローチャート

```mermaid
flowchart TD
    A[APIリクエスト受信] --> B["PagesAPIRouteModule.render()"]
    B --> C["apiResolver()"]
    C --> D[Cookie解析]
    D --> E{bodyParser有効?}
    E -->|Yes| F[ボディパース]
    E -->|No| G[ボディそのまま]
    F --> H[プレビューモード判定]
    G --> H
    H --> I[NextApiRequest/NextApiResponse構築]
    I --> J["handler(req, res) ← ユーザー定義関数"]
    J --> K{レスポンス送信済み?}
    K -->|Yes| L[処理完了]
    K -->|No| M[タイムアウトまたはエラー]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-30-01 | default export必須 | ハンドラ関数はdefaultエクスポートが必要 | 常時 |
| BR-30-02 | bodyParser設定 | `export const config = { api: { bodyParser: false } }`でボディパーサー無効化可能 | config.api.bodyParser参照時 |
| BR-30-03 | レスポンスサイズ制限 | デフォルトのレスポンスサイズ制限（4MB） | config.api.responseLimitで変更可能 |
| BR-30-04 | 204/304ボディ無視 | ステータスコード204/304の場合、ボディは送信されない | 該当ステータス設定時 |
| BR-30-05 | ETag自動生成 | JSONレスポンス等に対してETagを自動生成 | レスポンスボディが存在する場合 |
| BR-30-06 | revalidate API | res.revalidate()によるISRオンデマンド再検証が可能 | ISRページとの連携時 |

### 計算ロジック

レスポンスサイズ制限：`getMaxContentLength(responseLimit)`で最大コンテンツ長を計算。デフォルトは`RESPONSE_LIMIT_DEFAULT`（4MB）。

## データベース操作仕様

### 操作別データベース影響一覧

該当なし。API Routes自体はデータベースに直接アクセスしないが、ユーザーハンドラ内でデータベースアクセスが行われる。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 500 | default未定義 | ページがdefault関数をエクスポートしていない | default関数をエクスポートする |
| 413 | レスポンスサイズ超過 | レスポンスがサイズ制限を超える | レスポンスを分割するか制限を変更 |
| - | ボディパースエラー | JSONパースに失敗 | リクエストのContent-Typeとボディを確認 |

### リトライ仕様

フレームワークレベルでのリトライはない。

## トランザクション仕様

該当なし。ユーザーハンドラ内での独自実装。

## パフォーマンス要件

- API Routesはサーバーレス関数としてデプロイ可能
- レスポンスサイズ制限によるメモリ保護
- ETag生成によるクライアントキャッシュ最適化

## セキュリティ考慮事項

- API Routesのコードはサーバーサイドのみで実行される
- CORS制御は開発者が手動で実装する必要がある
- ボディパーサーの無効化により、ストリーム処理やカスタムパーサーの使用が可能

## 備考

- App RouterではRoute Handlers（`route.ts`）がAPI Routesの代替
- API RoutesはPages Router専用の機能
- API RoutesはSSG/ISRページのrevalidateトリガーとして使用できる

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

PagesAPIRouteModuleの型定義とモジュール構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | module.ts | `packages/next/src/server/route-modules/pages-api/module.ts` | `PagesAPIUserlandModule`型（23-33行目）とコンテキスト型の定義 |

**読解のコツ**: `PagesAPIUserlandModule`はdefaultエクスポート（ハンドラ関数）と任意のconfig（PageConfig）を持つ。ハンドラ関数は`(req: IncomingMessage, res: ServerResponse) => Promise<void>`型。

#### Step 2: エントリーポイントを理解する

PagesAPIRouteModule.render()がメインエントリーポイント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | module.ts | `packages/next/src/server/route-modules/pages-api/module.ts` | `render()`メソッド（136-161行目）がapiResolverWrappedに委譲 |

**主要処理フロー**:
1. **115-128行目**: コンストラクタでdefaultエクスポートの存在チェックとapiResolverのラップ
2. **142-160行目**: apiResolverWrappedにクエリ、ユーザーモジュール、各種設定を渡して実行

#### Step 3: apiResolverを理解する

APIリクエストの処理の核となるロジック。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | api-resolver.ts | `packages/next/src/server/api-utils/node/api-resolver.ts` | リクエストのパース、NextApiRequest/NextApiResponseの構築、ハンドラ実行 |

**主要処理フロー**:
- **58-78行目**: `sendData()`関数でレスポンスボディの送信（204/304ステータス処理、ストリーム対応、ETag生成）
- **45-50行目**: レスポンスサイズ制限の計算

#### Step 4: ヘルパー関数を理解する

NextApiRequest/NextApiResponseの拡張ヘルパー。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.ts | `packages/next/src/server/api-utils/index.ts` | setLazyProp、sendStatusCode、redirect等のヘルパー関数 |
| 4-2 | parse-body.ts | `packages/next/src/server/api-utils/node/parse-body.ts` | リクエストボディのパースロジック |

### プログラム呼び出し階層図

```
PagesAPIRouteModule.render() [module.ts:136]
    |
    +-- apiResolverWrapped() [api-resolver.ts]
            |
            +-- getCookieParser() - Cookie解析
            +-- parseBody() - ボディパース
            +-- tryGetPreviewData() - プレビューモード判定
            |
            +-- NextApiRequest/NextApiResponse構築
            |       +-- res.json() ヘルパー
            |       +-- res.status() ヘルパー
            |       +-- res.redirect() ヘルパー
            |       +-- res.revalidate() ヘルパー
            |
            +-- handler(req, res) ← ユーザー定義関数
            |
            +-- sendData() - レスポンス送信
                    +-- generateETag()
                    +-- sendEtagResponse()
```

### データフロー図

```
[入力]                         [処理]                              [出力]

HTTPリクエスト           ──> apiResolver                       ──> 前処理
(req, res, query)              |
                               |
req                     ──> Cookie解析 + ボディパース           ──> NextApiRequest
                               |
res                     ──> ヘルパーメソッド注入               ──> NextApiResponse
                               |
handler(req, res)       ──> ユーザー定義関数実行               ──> レスポンス
                               |
レスポンスボディ        ──> ETag生成 + サイズ検証              ──> HTTPレスポンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| module.ts | `packages/next/src/server/route-modules/pages-api/module.ts` | ソース | PagesAPIRouteModuleのメイン実装 |
| api-resolver.ts | `packages/next/src/server/api-utils/node/api-resolver.ts` | ソース | APIリクエスト処理の核（apiResolver関数） |
| index.ts | `packages/next/src/server/api-utils/index.ts` | ソース | APIユーティリティ（ヘルパー関数） |
| parse-body.ts | `packages/next/src/server/api-utils/node/parse-body.ts` | ソース | リクエストボディパース |
| try-get-preview-data.ts | `packages/next/src/server/api-utils/node/try-get-preview-data.ts` | ソース | プレビューモードデータ取得 |
| get-cookie-parser.ts | `packages/next/src/server/api-utils/get-cookie-parser.ts` | ソース | Cookie解析 |
| pages-api-route-definition.ts | `packages/next/src/server/route-definitions/pages-api-route-definition.ts` | ソース | API Routeルート定義型 |
