# 機能設計書 27-getServerSideProps

## 概要

本ドキュメントは、Next.js Pages RouterにおけるgetServerSideProps機能の設計を記述する。getServerSidePropsは、リクエスト時にサーバーサイドでデータを取得し、ページコンポーネントのpropsとして注入するAPIである。

### 本機能の処理概要

**業務上の目的・背景**：Webアプリケーションでは、ユーザーごとに異なるデータやリアルタイムデータを表示する必要がある。getServerSidePropsは、各リクエスト時にサーバーサイドでデータを取得してSSR（Server-Side Rendering）を行う仕組みを提供する。認証情報に基づくパーソナライズドコンテンツ、リアルタイムの在庫情報表示、ABテスト結果の表示など、キャッシュが不適切なケースで使用される。

**機能の利用シーン**：ユーザー認証情報に基づくダッシュボード表示、リアルタイムの商品在庫表示、パーソナライズされたフィード表示、リクエストヘッダー/Cookie依存のコンテンツ配信など。

**主要な処理内容**：
1. リクエスト時にgetServerSideProps関数を実行
2. コンテキスト（req/res/query/params/preview等）の提供
3. 戻り値のバリデーション（props/redirect/notFoundの排他チェック）
4. propsのシリアライズ検証
5. ページコンポーネントへのprops注入とSSRレンダリング

**関連システム・外部連携**：Pages Routerのレンダリングパイプライン、プレビューモード（Draft Mode）、外部データベース/APIとの連携。

**権限による制御**：getServerSideProps内でreq.cookiesやreq.headersを用いた認証チェックが可能。`redirect`戻り値により未認証ユーザーのリダイレクトを実装できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | エラーページ (_error) | 結果表示画面 | getServerSidePropsのエラー時にエラーページを表示 |
| 3 | アプリケーションラッパー (_app) | 補助機能 | getInitialPropsによる初期データ取得と統合 |

## 機能種別

データ取得 / SSRデータフェッチ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context.req | IncomingMessage | Yes | HTTPリクエストオブジェクト | Node.js標準 |
| context.res | ServerResponse | Yes | HTTPレスポンスオブジェクト | Node.js標準 |
| context.query | ParsedUrlQuery | Yes | URLクエリパラメータ | オブジェクト |
| context.params | Record<string, string> | No | 動的ルートパラメータ | 動的ルートの場合のみ |
| context.preview | boolean | No | プレビューモードフラグ | Draft Mode有効時true |
| context.previewData | PreviewData | No | プレビューデータ | Draft Mode有効時 |
| context.resolvedUrl | string | Yes | 内部リライトを解決したURL | 文字列 |
| context.locale | string | No | 現在のロケール | i18n有効時 |
| context.locales | string[] | No | サポートロケール一覧 | i18n有効時 |
| context.defaultLocale | string | No | デフォルトロケール | i18n有効時 |

### 入力データソース

- HTTPリクエスト情報（ヘッダー、Cookie、URL）
- 外部API/データベース（ユーザー実装部分）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| props | Record<string, any> | ページコンポーネントに渡すprops（シリアライズ可能） |
| redirect | { destination: string, permanent: boolean } | リダイレクト指定 |
| notFound | boolean | 404表示指定 |

### 出力先

- ページコンポーネントのpropsとして注入
- `__NEXT_DATA__`スクリプトタグ経由でクライアントに送信

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ サーバーがリクエストを受信し、該当ページのgetServerSidePropsを特定
2. プレビュー判定
   └─ previewCookieの存在を確認し、プレビューモードの有無を判定
3. getServerSideProps実行
   └─ コンテキストオブジェクトを構築してユーザー定義関数を実行
4. 戻り値バリデーション
   └─ props/redirect/notFoundの排他チェック、シリアライズ検証
5. リダイレクト/notFound処理
   └─ redirect指定時はリダイレクトレスポンス、notFound時は404レスポンスを返す
6. SSRレンダリング
   └─ 取得したpropsでページコンポーネントをサーバーサイドレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B[プレビューモード判定]
    B --> C[コンテキスト構築]
    C --> D["getServerSideProps(context)"]
    D --> E{戻り値}
    E -->|redirect| F[リダイレクトレスポンス]
    E -->|notFound: true| G[404レスポンス]
    E -->|props| H[propsバリデーション]
    H --> I{シリアライズ可能?}
    I -->|No| J[エラー]
    I -->|Yes| K[SSRレンダリング]
    K --> L[HTML + __NEXT_DATA__レスポンス]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-27-01 | サーバー専用 | getServerSidePropsのコードはクライアントバンドルに含まれない | 常時 |
| BR-27-02 | 排他的戻り値 | props、redirect、notFoundは排他的に返す | 常時 |
| BR-27-03 | シリアライズ可能 | propsはJSON.stringifyでシリアライズ可能でなければならない | props返却時 |
| BR-27-04 | リクエスト毎実行 | 毎回のリクエストで関数が実行される（キャッシュなし） | 常時 |
| BR-27-05 | output:export不可 | `output: 'export'`設定時はgetServerSidePropsは使用不可 | nextConfigOutput === 'export' |
| BR-27-06 | コンポーネントメンバー禁止 | getServerSidePropsはページコンポーネントのプロパティとして定義不可 | 常時（ファイルレベルエクスポートが必要） |

### 計算ロジック

戻り値の検証：`GSSP_NO_RETURNED_VALUE`エラーは戻り値がオブジェクトでない場合にスローされる。

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

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

該当なし。getServerSideProps自体はデータベースに直接アクセスしないが、ユーザー実装部分でデータベースアクセスが行われる。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | GSSP_NO_RETURNED_VALUE | 戻り値がオブジェクトでない | props/redirect/notFoundを含むオブジェクトを返す |
| - | SERVER_PROPS_GET_INIT_PROPS_CONFLICT | getInitialPropsと共存 | いずれかを削除 |
| - | SERVER_PROPS_SSG_CONFLICT | getStaticPropsと共存 | いずれかを削除 |
| - | シリアライズエラー | propsがシリアライズ不可 | 関数、Date、undefined等を除外 |

### リトライ仕様

フレームワークレベルでのリトライはない。getServerSideProps内でユーザーが独自にリトライを実装可能。

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

該当なし。ユーザー実装部分でのトランザクション管理。

## パフォーマンス要件

- getServerSidePropsはリクエスト毎に実行されるため、レスポンス時間に直接影響
- Cache-Controlヘッダーを設定することでCDNキャッシュが可能
- OpenTelemetryトレーシングにより実行時間を計測可能（`getServerSideProps`スパン）

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

- getServerSideProps内のコードはサーバーサイドのみで実行され、クライアントバンドルに含まれない
- APIキーやデータベース認証情報を安全に使用可能
- propsとして返したデータはクライアントに露出するため、機密情報を含めない注意が必要

## 備考

- App Routerでは Server Componentsの直接的なasync/awaitによるデータフェッチが推奨される
- getServerSidePropsはPages Router専用のAPI
- クライアントサイドナビゲーション時はJSON形式でデータが取得される

---

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

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

### 推奨読解順序

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

getServerSidePropsの型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/next/src/types.ts` | `GetServerSideProps`型と`GetServerSidePropsContext`型の定義 |

**読解のコツ**: `GetServerSidePropsResult<P>`はunion型で`{ props: P }`、`{ redirect: Redirect }`、`{ notFound: true }`のいずれかを返す。

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

render.tsxでのgetServerSideProps実行フロー。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | render.tsx | `packages/next/src/server/render.tsx` | renderToHTMLImpl内でのgetServerSideProps呼び出し（493行目付近でのデストラクチャリング、569-579行目の排他チェック） |

**主要処理フロー**:
1. **493行目**: `getServerSideProps`の取得
2. **569行目**: getInitialPropsとの共存チェック
3. **573行目**: getStaticPropsとの共存チェック
4. **577-580行目**: output: exportとの非互換チェック

#### Step 3: 実行とバリデーションを理解する

getServerSidePropsの実行と戻り値の処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | render.tsx | `packages/next/src/server/render.tsx` | getServerSidePropsの実行、戻り値のバリデーション、redirect/notFound処理 |

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

```
renderToHTMLImpl() [render.tsx]
    |
    +-- getServerSideProps判定 / 排他チェック
    |
    +-- プレビューモード判定
    |
    +-- getServerSideProps(context) ← ユーザー定義関数
    |       |
    |       +-- 戻り値バリデーション
    |       +-- redirect処理
    |       +-- notFound処理
    |       +-- isSerializableProps() 検証
    |
    +-- SSRレンダリング
            +-- App + Page + propsで描画
```

### データフロー図

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

HTTPリクエスト           ──> コンテキスト構築                   ──> GSSPContext
(req, res, query)              |
                               |
GSSPContext              ──> getServerSideProps(context)        ──> {props} | {redirect} | {notFound}
                               |
{props}                  ──> isSerializableProps() 検証         ──> validatedProps
                               |
validatedProps           ──> SSRレンダリング                    ──> HTML + __NEXT_DATA__
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| render.tsx | `packages/next/src/server/render.tsx` | ソース | getServerSideProps実行とSSRレンダリング |
| types.ts | `packages/next/src/types.ts` | ソース | GetServerSideProps型定義 |
| module.ts | `packages/next/src/server/route-modules/pages/module.ts` | ソース | PagesRouteModuleでのgetServerSideProps参照 |
| is-serializable-props.ts | `packages/next/src/lib/is-serializable-props.ts` | ソース | propsのシリアライズ検証 |
| constants.ts | `packages/next/src/lib/constants.ts` | ソース | エラーメッセージ定数 |
