# 機能設計書 11-REST API

## 概要

本ドキュメントは、Payload CMSにおけるREST APIエンドポイント機能の設計を定義する。コレクションおよびグローバルデータに対するHTTPベースのCRUD操作を提供し、外部システムやフロントエンドアプリケーションとのデータ連携を実現する。

### 本機能の処理概要

REST APIは、Payload CMSが管理するコレクション（複数ドキュメント）とグローバル（単一ドキュメント）に対して、HTTPリクエストを通じたデータ操作インターフェースを提供する機能である。

**業務上の目的・背景**：CMSのコンテンツを外部のWebサイト、モバイルアプリ、サードパーティサービスから取得・更新するための標準的なAPIインターフェースが必要である。REST APIは業界標準のHTTPプロトコルを使用し、言語やフレームワークに依存しない汎用的なデータアクセス手段を提供する。これにより、ヘッドレスCMSアーキテクチャを実現し、フロントエンドとバックエンドの分離開発を可能にする。

**機能の利用シーン**：
- フロントエンドアプリケーションからのコンテンツ取得（記事一覧、詳細表示）
- 外部システムからのデータ同期・インポート
- モバイルアプリケーションからのコンテンツ管理
- Webhook連携によるコンテンツ更新通知受信後の処理
- 管理画面（Admin UI）からのデータ操作

**主要な処理内容**：
1. コレクションエンドポイント：ドキュメントの作成、一覧取得、個別取得、更新、削除、カウント、複製
2. グローバルエンドポイント：グローバルデータの取得と更新
3. バージョン操作：バージョン一覧取得、特定バージョン取得、バージョン復元
4. アクセス制御：ドキュメントレベルの権限チェック
5. クエリパラメータ処理：ページネーション、フィルタリング、ソート、フィールド選択

**関連システム・外部連携**：
- データベースアダプター（MongoDB、PostgreSQL、SQLite等）との連携
- 認証システム（JWT、APIキー）との統合
- CORS設定による外部オリジンからのアクセス制御

**権限による制御**：
- コレクション設定の`access`オブジェクトで定義された権限に基づき、create/read/update/delete操作の可否を制御
- フィールドレベルのアクセス制御により、特定フィールドの表示・編集を制限
- `overrideAccess`オプションによるサーバーサイドからの権限バイパス

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | 一覧画面 | API連携 | ドキュメント一覧のフェッチ処理 |
| 10 | ドキュメント編集画面 | API連携 | ドキュメント保存時のAPI呼び出し |
| 11 | ゴミ箱画面 | API連携 | 削除済みドキュメントのフェッチ処理 |
| 14 | バージョン一覧画面 | API連携 | バージョンデータのフェッチ処理 |
| 17 | APIビュー画面 | 主機能 | ドキュメントのAPIレスポンス表示 |

## 機能種別

CRUD操作 / APIエンドポイント

## 入力仕様

### 入力パラメータ

#### コレクション共通パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| depth | number | No | リレーションの展開深度 | 0以上の整数 |
| draft | boolean | No | ドラフトを含めるか | true/false |
| populate | object | No | 展開するリレーションフィールド | フィールドパス指定 |
| select | object | No | 取得するフィールドの選択 | フィールドパス指定 |
| locale | string | No | 取得するロケール | 設定されたロケールコード |

#### find（一覧取得）固有パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| where | object | No | フィルタ条件 | クエリ演算子形式 |
| sort | string/array | No | ソート条件 | フィールド名（-で降順） |
| limit | number | No | 取得件数上限 | 0以上の整数 |
| page | number | No | ページ番号 | 1以上の整数 |
| pagination | boolean | No | ページネーション有効化 | true/false |
| joins | object | No | JOIN取得設定 | JOIN設定オブジェクト |
| trash | boolean | No | ゴミ箱のドキュメントを含めるか | true/false |

#### create（作成）固有パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| data | object | Yes | 作成するドキュメントデータ | コレクションスキーマに準拠 |
| autosave | boolean | No | 自動保存モード | true/false |
| publishAllLocales | boolean | No | 全ロケール公開 | true/false |
| publishSpecificLocale | string | No | 特定ロケールのみ公開 | ロケールコード |

#### updateByID（ID指定更新）固有パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | string/number | Yes | 更新対象のドキュメントID | 有効なID形式 |
| data | object | Yes | 更新データ | コレクションスキーマに準拠 |
| overrideLock | boolean | No | ロック状態を無視して更新 | true/false |
| unpublishAllLocales | boolean | No | 全ロケール非公開 | true/false |

### 入力データソース

- HTTPリクエストボディ（JSON形式）
- URLパスパラメータ（ID等）
- クエリストリング（検索条件、オプション）

## 出力仕様

### 出力データ

#### 単一ドキュメント取得時

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (ドキュメント) | object | ドキュメントのフィールド値 |
| id | string/number | ドキュメントID |
| createdAt | string | 作成日時（ISO 8601形式） |
| updatedAt | string | 更新日時（ISO 8601形式） |

#### 一覧取得時（PaginatedDocs）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| docs | array | ドキュメント配列 |
| totalDocs | number | 総ドキュメント数 |
| limit | number | 取得件数上限 |
| totalPages | number | 総ページ数 |
| page | number | 現在のページ番号 |
| pagingCounter | number | ページングカウンター |
| hasPrevPage | boolean | 前ページ存在フラグ |
| hasNextPage | boolean | 次ページ存在フラグ |
| prevPage | number/null | 前ページ番号 |
| nextPage | number/null | 次ページ番号 |

#### 作成・更新時

| 項目名 | 型 | 説明 |
|--------|-----|------|
| doc | object | 作成/更新されたドキュメント |
| message | string | 処理結果メッセージ |

### 出力先

- HTTPレスポンスボディ（JSON形式）
- HTTPステータスコード（200, 201, 400, 401, 403, 404, 500等）
- CORSヘッダー

## 処理フロー

### 処理シーケンス

```
1. HTTPリクエスト受信
   └─ Next.js App Routerがリクエストをハンドリング

2. エンドポイントルーティング
   └─ パスとHTTPメソッドに基づいて適切なハンドラーを選択

3. パラメータパース
   └─ クエリストリング、リクエストボディの解析・型変換

4. beforeOperation フック実行
   └─ コレクション設定のbeforeOperationフックを呼び出し

5. アクセス制御
   └─ コレクションのaccessオブジェクトに基づく権限チェック

6. データベース操作
   └─ データベースアダプターを通じたCRUD操作実行

7. afterRead/afterChange フック実行
   └─ フィールドレベル・コレクションレベルのフック処理

8. afterOperation フック実行
   └─ 操作完了後のフック処理

9. レスポンス生成
   └─ JSON形式でレスポンスを構築、CORSヘッダー付加

10. HTTPレスポンス送信
    └─ 適切なステータスコードとともにレスポンスを返却
```

### フローチャート

```mermaid
flowchart TD
    A[HTTPリクエスト受信] --> B[エンドポイントルーティング]
    B --> C[パラメータパース]
    C --> D[beforeOperation フック]
    D --> E{アクセス制御}
    E -->|許可| F[データベース操作]
    E -->|拒否| G[403 Forbidden]
    F --> H[afterRead/afterChange フック]
    H --> I[afterOperation フック]
    I --> J[レスポンス生成]
    J --> K[HTTPレスポンス送信]
    G --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ページネーションデフォルト | limitが未指定の場合、デフォルト値10を使用 | find操作時 |
| BR-02 | ドラフト除外 | draft=trueが指定されない限りドラフトは除外 | バージョン管理有効時 |
| BR-03 | ゴミ箱除外 | trash=trueが指定されない限り削除済みは除外 | trash機能有効時 |
| BR-04 | CORS制御 | 設定されたオリジンのみアクセス許可 | 外部オリジンからのリクエスト |
| BR-05 | ロケールフォールバック | 指定ロケールにデータがない場合はフォールバックロケールを使用 | 多言語設定時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| create | {collection} | INSERT | 新規ドキュメント作成 |
| find | {collection} | SELECT | ドキュメント一覧取得 |
| findByID | {collection} | SELECT | 単一ドキュメント取得 |
| updateByID | {collection} | UPDATE | 単一ドキュメント更新 |
| update | {collection} | UPDATE | 条件に合致する複数ドキュメント更新 |
| deleteByID | {collection} | DELETE/UPDATE | 単一ドキュメント削除（ゴミ箱移動または物理削除） |
| delete | {collection} | DELETE/UPDATE | 条件に合致する複数ドキュメント削除 |
| count | {collection} | SELECT | ドキュメント数カウント |
| duplicate | {collection} | INSERT | ドキュメント複製 |
| findVersions | {collection}_versions | SELECT | バージョン一覧取得 |
| restoreVersion | {collection}, {collection}_versions | UPDATE/INSERT | バージョン復元 |

### テーブル別操作詳細

#### {collection}テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | 全フィールド | リクエストボディの値 | beforeChangeフック適用後 |
| UPDATE | 指定フィールド | リクエストボディの値 | マージ更新 |
| DELETE | - | where条件に合致 | 物理削除またはソフト削除 |
| SELECT | select指定フィールド | where条件に合致 | フィールド選択可能 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | Bad Request | 不正なリクエストパラメータ | パラメータ形式を確認 |
| 401 | Unauthorized | 認証が必要なエンドポイントで未認証 | 認証トークンを付与 |
| 403 | Forbidden | アクセス権限なし | 権限を確認 |
| 404 | Not Found | 指定IDのドキュメントが存在しない | IDを確認 |
| 500 | Internal Server Error | サーバー内部エラー | サーバーログを確認 |

### リトライ仕様

クライアント側でのリトライを推奨。サーバー側での自動リトライは実装されていない。

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

- create、updateByID、deleteByID操作はトランザクション内で実行
- `disableTransaction`オプションでトランザクションを無効化可能
- エラー発生時は自動ロールバック
- `initTransaction`で開始、`commitTransaction`で確定、`killTransaction`でロールバック

## パフォーマンス要件

- 一覧取得：1000件以下で1秒以内のレスポンス推奨
- ページネーション使用により大量データ取得時のパフォーマンス確保
- `select`パラメータによる不要フィールド除外で転送量削減
- `depth`制限によるリレーション展開の最適化

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

- JWT認証またはAPIキー認証によるリクエスト認証
- コレクション/フィールドレベルのアクセス制御
- CORS設定による許可オリジンの制限
- SQLインジェクション対策（パラメータバインディング）
- 入力バリデーションによる不正データ排除

## 備考

- REST APIエンドポイントはNext.js App Routerと統合されている
- カスタムエンドポイントの追加は`endpoints`設定で可能
- GraphQL APIとの併用が可能

---

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

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

### 推奨読解順序

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

まず、REST APIで使用される型定義とエンドポイント構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/payload/src/config/types.ts` | PayloadHandler、Endpoint型の定義を確認 |
| 1-2 | index.ts | `packages/payload/src/types/index.ts` | PayloadRequest、Where、PopulateType等の共通型定義 |

**読解のコツ**: `PayloadHandler`型（339行目）はWebのRequest/Responseモデルに準拠しており、`(req: PayloadRequest) => Promise<Response> | Response`という形式。`Endpoint`型（344行目）はhandler、method、pathを持つオブジェクト。

#### Step 2: エンドポイント登録を理解する

コレクションとグローバルのデフォルトエンドポイントがどのように定義されているかを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/payload/src/collections/endpoints/index.ts` | コレクションのデフォルトエンドポイント一覧 |
| 2-2 | index.ts | `packages/payload/src/globals/endpoints/index.ts` | グローバルのデフォルトエンドポイント一覧 |

**主要処理フロー**:
1. **19-93行目**（collections/endpoints/index.ts）: `defaultCollectionEndpoints`配列でcount、create、delete、find、updateなど14種類のエンドポイントを定義
2. **11-42行目**（globals/endpoints/index.ts）: `defaultGlobalEndpoints`配列でdocAccess、findOne、findVersions、restoreVersion、updateを定義

#### Step 3: ハンドラー実装を理解する

各HTTPリクエストを処理するハンドラーの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create.ts | `packages/payload/src/collections/endpoints/create.ts` | POST /でドキュメント作成 |
| 3-2 | find.ts | `packages/payload/src/collections/endpoints/find.ts` | GET /でドキュメント一覧取得 |
| 3-3 | findByID.ts | `packages/payload/src/collections/endpoints/findByID.ts` | GET /:idで単一ドキュメント取得 |
| 3-4 | updateByID.ts | `packages/payload/src/collections/endpoints/updateByID.ts` | PATCH /:idでドキュメント更新 |
| 3-5 | deleteByID.ts | `packages/payload/src/collections/endpoints/deleteByID.ts` | DELETE /:idでドキュメント削除 |

**主要処理フロー**（create.ts）:
- **11-12行目**: ハンドラー関数定義、リクエストからコレクション情報取得
- **14行目**: `parseParams`でクエリパラメータを型変換
- **18-29行目**: `createOperation`を呼び出してドキュメント作成
- **31-45行目**: 成功レスポンス（HTTP 201）を生成、CORSヘッダー付加

#### Step 4: Operations層を理解する

実際のビジネスロジックが実装されているOperations層を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | create.ts | `packages/payload/src/collections/operations/create.ts` | ドキュメント作成のビジネスロジック |
| 4-2 | find.ts | `packages/payload/src/collections/operations/find.ts` | 一覧取得のビジネスロジック |

**主要処理フロー**（operations/create.ts）:
- **71-72行目**: トランザクション開始
- **86-91行目**: beforeOperationフック実行
- **154-156行目**: アクセス制御チェック
- **181-190行目**: beforeValidateフック実行
- **232-243行目**: beforeChangeフック実行
- **307-311行目**: データベースへの書き込み（payload.db.create）
- **329-341行目**: バージョン保存
- **363-377行目**: afterReadフック実行
- **400-409行目**: afterChangeフック実行
- **449-451行目**: トランザクションコミット

#### Step 5: ユーティリティを理解する

パラメータ解析やCORSヘッダー処理などのユーティリティを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | index.ts | `packages/payload/src/utilities/parseParams/index.ts` | クエリパラメータの型変換 |
| 5-2 | headersWithCors.ts | `packages/payload/src/utilities/headersWithCors.ts` | CORSヘッダー設定 |

**主要処理フロー**（parseParams/index.ts）:
- **58-65行目**: ブール値パラメータのリスト（draft、trash等）
- **67行目**: 数値パラメータのリスト（depth、limit、page）
- **76-115行目**: 各パラメータタイプに応じた変換処理

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

```
HTTPリクエスト (Next.js App Router)
    │
    ├─ collections/endpoints/create.ts (createHandler)
    │      ├─ getRequestCollection()
    │      ├─ parseParams()
    │      ├─ createOperation()
    │      │      ├─ initTransaction()
    │      │      ├─ buildBeforeOperation()
    │      │      ├─ executeAccess()
    │      │      ├─ generateFileData()
    │      │      ├─ beforeValidate()
    │      │      ├─ beforeChange()
    │      │      ├─ payload.db.create()
    │      │      ├─ saveVersion()
    │      │      ├─ afterRead()
    │      │      ├─ afterChange()
    │      │      ├─ buildAfterOperation()
    │      │      └─ commitTransaction()
    │      └─ headersWithCors()
    │
    ├─ collections/endpoints/find.ts (findHandler)
    │      ├─ getRequestCollection()
    │      ├─ parseParams()
    │      ├─ findOperation()
    │      │      ├─ buildBeforeOperation()
    │      │      ├─ executeAccess()
    │      │      ├─ combineQueries()
    │      │      ├─ payload.db.find()
    │      │      ├─ afterRead()
    │      │      └─ buildAfterOperation()
    │      └─ headersWithCors()
    │
    └─ (他のエンドポイントも同様の構造)
```

### データフロー図

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

HTTPリクエスト ─────▶ Endpoint Handler ─────▶ HTTPレスポンス
  ├─ Headers                  │                    ├─ Status Code
  ├─ URL Params               │                    ├─ Headers (CORS)
  ├─ Query String             ▼                    └─ JSON Body
  └─ Body (JSON)        Operation Layer
                              │
                              ├─ フック処理
                              │   ├─ beforeOperation
                              │   ├─ beforeValidate
                              │   ├─ beforeChange
                              │   ├─ afterRead
                              │   ├─ afterChange
                              │   └─ afterOperation
                              │
                              ├─ アクセス制御
                              │   └─ executeAccess()
                              │
                              └─ DB操作
                                  └─ payload.db.create/find/update/delete
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/payload/src/collections/endpoints/index.ts` | ソース | コレクションエンドポイント定義 |
| create.ts | `packages/payload/src/collections/endpoints/create.ts` | ソース | ドキュメント作成ハンドラー |
| find.ts | `packages/payload/src/collections/endpoints/find.ts` | ソース | 一覧取得ハンドラー |
| findByID.ts | `packages/payload/src/collections/endpoints/findByID.ts` | ソース | 単一取得ハンドラー |
| updateByID.ts | `packages/payload/src/collections/endpoints/updateByID.ts` | ソース | 更新ハンドラー |
| deleteByID.ts | `packages/payload/src/collections/endpoints/deleteByID.ts` | ソース | 削除ハンドラー |
| delete.ts | `packages/payload/src/collections/endpoints/delete.ts` | ソース | 一括削除ハンドラー |
| update.ts | `packages/payload/src/collections/endpoints/update.ts` | ソース | 一括更新ハンドラー |
| count.ts | `packages/payload/src/collections/endpoints/count.ts` | ソース | カウントハンドラー |
| duplicate.ts | `packages/payload/src/collections/endpoints/duplicate.ts` | ソース | 複製ハンドラー |
| docAccess.ts | `packages/payload/src/collections/endpoints/docAccess.ts` | ソース | アクセス権限チェック |
| findVersions.ts | `packages/payload/src/collections/endpoints/findVersions.ts` | ソース | バージョン一覧ハンドラー |
| restoreVersion.ts | `packages/payload/src/collections/endpoints/restoreVersion.ts` | ソース | バージョン復元ハンドラー |
| index.ts | `packages/payload/src/globals/endpoints/index.ts` | ソース | グローバルエンドポイント定義 |
| findOne.ts | `packages/payload/src/globals/endpoints/findOne.ts` | ソース | グローバル取得ハンドラー |
| update.ts | `packages/payload/src/globals/endpoints/update.ts` | ソース | グローバル更新ハンドラー |
| create.ts | `packages/payload/src/collections/operations/create.ts` | ソース | 作成操作ロジック |
| find.ts | `packages/payload/src/collections/operations/find.ts` | ソース | 一覧取得操作ロジック |
| index.ts | `packages/payload/src/utilities/parseParams/index.ts` | ソース | パラメータ解析 |
| headersWithCors.ts | `packages/payload/src/utilities/headersWithCors.ts` | ソース | CORSヘッダー処理 |
| types.ts | `packages/payload/src/config/types.ts` | ソース | 型定義 |
