# 機能設計書 118-マルチゾーン

## 概要

本ドキュメントは、Next.jsのマルチゾーン機能の設計を記載する。複数のNext.jsアプリケーションを単一ドメインで統合し、各アプリケーション（ゾーン）がそれぞれのbasePathでURLスペースを分割して運用する仕組みを定義する。

### 本機能の処理概要

**業務上の目的・背景**：大規模なWebサービスでは、マイクロフロントエンドアーキテクチャのように、異なるチームが担当するアプリケーションを単一ドメイン下で統合運用する需要がある。マルチゾーンはbasePath設定とリライトルールを組み合わせることで、複数のNext.jsアプリケーションを一つのドメインで透過的にアクセス可能にする。

**機能の利用シーン**：複数チームが独立してNext.jsアプリケーションを開発・デプロイし、同一ドメインで統合する場面、既存のアプリケーションに段階的に新しいNext.jsアプリケーションを追加する場面、アプリケーションの分割リファクタリングを行う場面で利用される。

**主要な処理内容**：
1. 各ゾーンのbasePath設定によるURLスペース分割
2. リライトルールによるゾーン間のリクエストルーティング
3. 各ゾーンの独立したビルドとデプロイ
4. Router Serverでのリクエスト振り分け処理

**関連システム・外部連携**：リバースプロキシ（Vercel、Nginx等）、各ゾーンのNext.jsサーバーと連携する。

**権限による制御**：特に権限制御はない。next.config.jsのbasePath設定とrewritesルールで制御される。

## 関連画面

本機能はインフラストラクチャレベルの構成であり、直接関連する画面は存在しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 各ゾーンのページはそれぞれの画面として独立して動作 |

## 機能種別

インフラストラクチャ構成・ルーティング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| basePath | string | Yes | アプリケーションのベースパス | '/'で始まること、末尾に'/'を含まないこと |
| rewrites | async function | No | リライトルール定義関数 | 有効なリライトルール |
| assetPrefix | string | No | 静的アセットのプレフィックス | 有効なURL |

### 入力データソース

- next.config.js / next.config.ts（各ゾーンの設定ファイル）
- リバースプロキシの設定（外部）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| HTML応答 | HTTP Response | 各ゾーンからのHTMLレスポンス |
| 静的アセット | ファイル | basePath付きのJS/CSS/画像ファイル |

### 出力先

- HTTPレスポンス（ブラウザ）
- CDN（静的アセット）

## 処理フロー

### 処理シーケンス

```
1. クライアントからのリクエスト受信
   └─ リバースプロキシまたはメインゾーンが受信
2. ルーティング判定
   └─ URLパスに基づき対象ゾーンを特定
3. リライト処理
   └─ rewritesルールに基づきリクエストを対象ゾーンに転送
4. ゾーンでの処理
   └─ 対象ゾーンのNext.jsサーバーがbasePath付きで処理
5. レスポンス返却
   └─ 処理結果をクライアントに返却
```

### フローチャート

```mermaid
flowchart TD
    A[クライアントリクエスト] --> B[リバースプロキシ/メインゾーン]
    B --> C{URLパス判定}
    C -->|/blog/*| D[Blog Zone basePath=/blog]
    C -->|/docs/*| E[Docs Zone basePath=/docs]
    C -->|その他| F[Main Zone basePath=/]
    D --> G[Blog Next.jsサーバー]
    E --> H[Docs Next.jsサーバー]
    F --> I[Main Next.jsサーバー]
    G --> J[レスポンス返却]
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | basePath一意性 | 各ゾーンのbasePathは重複してはならない | マルチゾーン構成時 |
| BR-02 | basePath形式 | basePathは'/'で始まり、末尾に'/'を含まない | 設定時 |
| BR-03 | 独立ビルド | 各ゾーンは独立してビルド・デプロイできる | 常時 |
| BR-04 | ゾーン間ナビゲーション | ゾーン間の遷移はハードナビゲーション（フルページリロード）となる | ゾーン間リンク時 |
| BR-05 | 静的アセット分離 | 各ゾーンの静的アセットはbasePath下に配置される | 常時 |

### 計算ロジック

特になし。

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

本機能はデータベースを使用しない。

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | basePath設定エラー | 無効なbasePath形式 | 設定バリデーションでエラー通知 |
| - | ゾーン到達不能 | 対象ゾーンのサーバーがダウン | リバースプロキシ側のフォールバック |

### リトライ仕様

各ゾーンへのリクエスト転送のリトライはリバースプロキシ側の設定に依存する。

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

トランザクション管理は不要。

## パフォーマンス要件

- リバースプロキシによる効率的なリクエストルーティング
- 各ゾーンの独立したスケーリングが可能
- ゾーン間ナビゲーション時のフルページリロードによるレイテンシ

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

- 各ゾーン間のCookie共有に注意（同一ドメイン内のため共有される）
- ゾーン間でのCSRF保護の一貫性を確保する必要がある
- 各ゾーンのセキュリティ設定は独立して管理される

## 備考

- マルチゾーンはVercelプラットフォームでのネイティブサポートが提供されている
- ゾーン間のナビゲーションにはnext/linkではなく`<a>`タグを使用する（ハードナビゲーション）
- assetPrefixを設定することで、各ゾーンの静的アセットを別のCDNから配信可能
- マルチゾーンはNext.jsの公式機能として「設定の組み合わせ」で実現される（専用APIは存在しない）

---

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

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

### 推奨読解順序

#### Step 1: 設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config-shared.ts | `packages/next/src/server/config-shared.ts` | basePath設定の型定義とデフォルト値（空文字列） |

**読解のコツ**: basePathのデフォルト値は空文字列（''）。マルチゾーンは明示的なAPIではなく、basePath + rewritesの組み合わせで実現される点に注意。

#### Step 2: basePath処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.ts | `packages/next/src/server/config.ts` | basePath設定のバリデーションと正規化 |

#### Step 3: リライトルールの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | load-custom-routes.ts | `packages/next/src/lib/load-custom-routes.ts` | rewritesルールの読み込みと構築 |

#### Step 4: Router Serverでの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | router-server.ts | `packages/next/src/server/lib/router-server.ts` | リクエストルーティングでのbasePath処理 |
| 4-2 | filesystem.ts | `packages/next/src/server/lib/router-utils/filesystem.ts` | ファイルシステムルーティングでのbasePath考慮 |

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

```
[リバースプロキシ / Vercel Edge]
    |
    +-- Zone A (basePath = '/')
    |       +-- router-server.ts
    |       +-- rewritesによる他ゾーンへの転送
    |
    +-- Zone B (basePath = '/blog')
    |       +-- router-server.ts
    |       +-- basePath付きリクエスト処理
    |
    +-- Zone C (basePath = '/docs')
            +-- router-server.ts
            +-- basePath付きリクエスト処理
```

### データフロー図

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

クライアント -----------> リバースプロキシ
  GET /blog/post-1             |
                          URLパス判定
                               |
                          Zone B (basePath=/blog)
                               |
                          router-server.ts
                               |
                          basePath除去 -> /post-1
                               |
                          ページレンダリング
                               |
                          HTML応答 -------> クライアント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config-shared.ts | `packages/next/src/server/config-shared.ts` | ソース | basePath設定の型定義 |
| config.ts | `packages/next/src/server/config.ts` | ソース | basePath設定のバリデーション |
| load-custom-routes.ts | `packages/next/src/lib/load-custom-routes.ts` | ソース | rewritesルールの読み込み |
| router-server.ts | `packages/next/src/server/lib/router-server.ts` | ソース | リクエストルーティング |
| filesystem.ts | `packages/next/src/server/lib/router-utils/filesystem.ts` | ソース | ファイルシステムルーティング |
