# 機能設計書 19-Server Actions

## 概要

本ドキュメントは、Next.js App RouterにおけるServer Actionsの設計を記述する。`'use server'` ディレクティブによるサーバーアクション定義機能であり、フォーム送信やデータ変更をサーバー側で直接処理する。

### 本機能の処理概要

Server Actionsは、クライアントからサーバーサイドの関数を直接呼び出す機能であり、フォーム送信やデータ変更等のミューテーション操作をサーバー側で安全に実行する。

**業務上の目的・背景**：従来のWebアプリケーションでは、サーバーサイドのデータ変更にはAPIエンドポイントの定義とクライアントからのfetch呼び出しが必要であった。Server Actionsにより、APIエンドポイントを明示的に定義することなく、サーバーサイドの関数をクライアントから呼び出せるようになり、フォーム処理やデータ変更のコードが大幅に簡素化される。

**機能の利用シーン**：フォーム送信処理、データベースの更新・削除操作、認証処理（ログイン・ログアウト）、キャッシュの再検証トリガー等で利用される。

**主要な処理内容**：
1. `'use server'` ディレクティブの検出とServer Reference変換
2. HTTPリクエストからのアクションメタデータ抽出（actionId、content-type等）
3. CSRF保護の検証
4. リクエストボディのデコード（multipart/application-json）
5. サーバーサイドでのアクション関数実行
6. 結果のシリアライゼーションとFlightペイロード生成
7. キャッシュ再検証ヘッダーの設定
8. 別ワーカーへのアクション転送（必要時）

**関連システム・外部連携**：CSRF保護、暗号化（クロージャデータ）、キャッシュ再検証システム。

**権限による制御**：CSRF保護によるオリジン検証、Server Actions暗号化によるクロージャデータ保護。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | Server ActionsはUI固有ではなく、フォーム送信やデータ変更に対するサーバーサイド処理基盤 |

## 機能種別

データ変更 / サーバーサイド処理 / CRUD操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| actionId | string | Yes | サーバーアクションの一意識別子 | Next-Action HTTPヘッダーから取得 |
| contentType | string | Yes | リクエストのContent-Type | multipart/form-data or application/json等 |
| body | FormData/JSON | Yes | アクションに渡す引数 | content-typeに応じたデコード |
| Origin | string | No | リクエスト元のオリジン | CSRF検証に使用 |

### 入力データソース

- HTMLフォーム送信（action属性）
- JavaScriptからのfetch呼び出し（startTransition経由）
- HTTPリクエストヘッダー（Next-Action、Content-Type、Origin等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| アクション結果 | Flight形式 | サーバーアクションの戻り値をシリアライズしたRSCペイロード |
| x-action-revalidated | ヘッダー | キャッシュ再検証の実行状況 |
| Set-Cookie | ヘッダー | Cookie変更（認証トークン等） |
| Location | ヘッダー | リダイレクト先URL（redirect呼び出し時） |

### 出力先

- HTTPレスポンス（RSCペイロード + ヘッダー）
- キャッシュ再検証システム

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信とメタデータ抽出
   └─ getServerActionRequestMetadataでactionId/contentType/isFetchAction等を取得
2. サーバーアクション存在チェック
   └─ hasServerActions()でアクションマニフェストを確認
3. CSRF保護検証
   └─ isCsrfOriginAllowedでオリジンを検証
4. アクション関数の解決
   └─ serverModuleMapからactionIdに対応する関数を取得
5. リクエストボディのデコード
   └─ multipart: decodeReply + FormData / JSON: decodeReply
6. アクション関数の実行
   └─ サーバーサイドでの関数呼び出しとエラーハンドリング
7. 結果のシリアライゼーション
   └─ generateFlight()でFlightペイロードを生成
8. 再検証ヘッダーの設定
   └─ addRevalidationHeaderでキャッシュ再検証情報を付与
9. レスポンス送信
   └─ FlightRenderResultとしてレスポンスを返却
```

### フローチャート

```mermaid
flowchart TD
    A[HTTPリクエスト受信] --> B{Server Action?}
    B -->|No| C[通常のレンダリング処理]
    B -->|Yes| D[actionId抽出]
    D --> E{アクション存在?}
    E -->|No| F[404: action not found]
    E -->|Yes| G[CSRF保護検証]
    G --> H{オリジン許可?}
    H -->|No| I[403: CSRF error]
    H -->|Yes| J[リクエストボディデコード]
    J --> K[アクション関数実行]
    K --> L{エラー発生?}
    L -->|Yes| M{リダイレクト/NotFound?}
    M -->|Yes| N[対応するレスポンス]
    M -->|No| O[エラーレスポンス]
    L -->|No| P[結果シリアライゼーション]
    P --> Q[再検証ヘッダー設定]
    Q --> R[Flightペイロード送信]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 'use server'宣言 | ファイル先頭または関数内で'use server'を宣言する必要がある | Server Action定義時 |
| BR-02 | CSRF保護 | fetchアクションにはオリジン検証が適用される | isFetchAction時 |
| BR-03 | 静的生成不可 | Server Actionsは静的生成（SSG）中には実行できない | isStaticGeneration時 |
| BR-04 | ワーカー転送 | アクションが現在のワーカーに存在しない場合、適切なワーカーに転送される | マルチワーカー環境 |
| BR-05 | アクション再検証 | revalidatePath/revalidateTagの呼び出しによりキャッシュ再検証ヘッダーが設定される | 再検証呼び出し時 |
| BR-06 | インラインアクション | $$RSC_SERVER_ACTION_プレフィックスのアクションはインラインアクション | インラインアクション時 |

### 計算ロジック

該当なし。

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

Server Action内で直接データベース操作が可能であるが、特定のデータベースとの結合はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Action Not Found | actionIdに対応するアクションが存在しない | NEXT_ACTION_NOT_FOUND_HEADERを設定 |
| 403 | CSRF Error | オリジン検証失敗 | 403ステータスを返却 |
| - | Redirect | action内でredirect()が呼ばれた | リダイレクトレスポンス生成 |
| - | Not Found | action内でnotFound()が呼ばれた | Not Foundレスポンス生成 |
| 500 | Server Error | アクション実行中の例外 | エラーFlightペイロード生成 |
| - | Static Generation Error | SSG中のアクション実行 | InvariantError throw |

### リトライ仕様

サーバーアクションにリトライ機構は組み込まれていない。クライアントサイドでのリトライは呼び出し元の責任。

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

Server Action自体にはトランザクション管理は含まれない。データベーストランザクションはアクション関数内で実装する。

## パフォーマンス要件

- Server ActionsのボディサイズはserverActions.bodySizeLimitで制限可能
- アクション実行後のFlightペイロード生成はストリーミング対応

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

- CSRF保護: isCsrfOriginAllowedによるオリジン検証
- クロージャデータの暗号化: Server Actionsのクロージャ変数は暗号化される
- アクションIDは推測困難なハッシュ値
- Server Actionsマニフェストによるアクションの存在検証

## 備考

- INLINE_ACTION_PREFIX = '$$RSC_SERVER_ACTION_' はインラインServer Actionのプレフィックス
- URL Encoded Actionsは現在サポートされていない
- MPA（Multi-Page Application）アクションとSPA（fetch）アクションで処理が分岐する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | app-router-headers.ts | `packages/next/src/client/components/app-router-headers.ts` | ACTION_HEADER、NEXT_ACTION_NOT_FOUND_HEADER等のヘッダー定数 |
| 1-2 | server-action-request-meta.ts | `packages/next/src/server/lib/server-action-request-meta.ts` | getServerActionRequestMetadataでリクエストメタデータの構造を理解 |

**読解のコツ**: Server ActionsはHTTPヘッダー（Next-Action等）でアクション種別を識別する。Content-Typeでmultipart（FormData）かJSON（fetch呼び出し）かを判断する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | action-handler.ts | `packages/next/src/server/app-render/action-handler.ts` | handleAction関数（531行目）がServer Actionsのメインエントリーポイント |

**主要処理フロー**:
1. **552-562行目**: リクエストメタデータの抽出
2. **582-587行目**: isPossibleServerActionチェック
3. **603-605行目**: hasServerActions()による存在チェック
4. **607-609行目**: 静的生成中の不正呼び出しチェック

#### Step 3: CSRF保護とアクション解決

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | csrf-protection.ts | `packages/next/src/server/app-render/csrf-protection.ts` | isCsrfOriginAllowedでのオリジン検証 |
| 3-2 | manifests-singleton.ts | `packages/next/src/server/app-render/manifests-singleton.ts` | getServerActionsManifest、getServerModuleMap |

#### Step 4: アクション転送とレスポンス生成

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | action-handler.ts | `packages/next/src/server/app-render/action-handler.ts` | createForwardedActionResponse（203行目）でのワーカー転送 |
| 4-2 | action-handler.ts | `packages/next/src/server/app-render/action-handler.ts` | addRevalidationHeader（144-198行目）での再検証ヘッダー設定 |

**主要処理フロー**:
- **76行目**: INLINE_ACTION_PREFIX定数の定義
- **81-88行目**: hasServerActions()でマニフェストからアクション存在確認
- **90-100行目**: nodeHeadersToRecordでヘッダー変換
- **102-142行目**: getForwardedHeadersでリクエスト転送用ヘッダー構築
- **144-198行目**: addRevalidationHeaderでキャッシュ再検証情報の設定

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

```
renderToHTMLOrFlight (app-render.tsx)
    |
    +-- handleAction (action-handler.ts)
           |
           +-- getServerActionRequestMetadata
           |      └─ actionId, isFetchAction, isMultipartAction 抽出
           |
           +-- hasServerActions
           |      └─ getServerActionsManifest で存在確認
           |
           +-- isCsrfOriginAllowed (csrf-protection.ts)
           |
           +-- selectWorkerForForwarding
           |      └─ createForwardedActionResponse (ワーカー転送)
           |
           +-- decodeReply (リクエストボディデコード)
           |
           +-- アクション関数実行
           |
           +-- generateFlight (Flightペイロード生成)
           |
           +-- addRevalidationHeader
           |
           +-- executeRevalidates (revalidation-utils.ts)
```

### データフロー図

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

HTTPリクエスト
  ├─ Next-Action ---------> getServerActionRequestMetadata
  ├─ Content-Type                    |
  ├─ Origin --------------> isCsrfOriginAllowed
  └─ Body (FormData/JSON)           |
                                     v
                             handleAction
                                     |
                             decodeReply ---------> アクション引数
                                     |
                             アクション関数実行 ---> 結果
                                     |
                             generateFlight -------> RSCペイロード
                                     |
                             addRevalidationHeader -> x-action-revalidated
                                     |
                                  レスポンス送信
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| action-handler.ts | `packages/next/src/server/app-render/action-handler.ts` | ソース | Server Actionsメインハンドラー |
| csrf-protection.ts | `packages/next/src/server/app-render/csrf-protection.ts` | ソース | CSRF保護 |
| encryption.ts | `packages/next/src/server/app-render/encryption.ts` | ソース | クロージャデータ暗号化 |
| manifests-singleton.ts | `packages/next/src/server/app-render/manifests-singleton.ts` | ソース | アクションマニフェスト管理 |
| server-action-request-meta.ts | `packages/next/src/server/lib/server-action-request-meta.ts` | ソース | リクエストメタデータ抽出 |
| app-router-headers.ts | `packages/next/src/client/components/app-router-headers.ts` | ソース | HTTPヘッダー定数 |
| revalidation-utils.ts | `packages/next/src/server/revalidation-utils.ts` | ソース | 再検証実行 |
| server-reference-info.ts | `packages/next/src/shared/lib/server-reference-info.ts` | ソース | Server Reference情報抽出 |
