# 機能設計書 65-REST API

## 概要

本ドキュメントは、Jenkins における HTTP 経由のリモートアクセス API（REST API）の設計について記述する。

### 本機能の処理概要

REST API 機能は、Jenkins の各種リソース（ジョブ、ビルド、ノード等）に対して HTTP 経由でプログラマティックにアクセスするための基盤機能である。XML、JSON、Python 形式でのデータ出力に対応している。

**業務上の目的・背景**：CI/CD システムは他のツールやスクリプトとの連携が不可欠である。REST API は、ビルドの自動トリガー、ステータス監視、設定の自動化など、Jenkins を外部システムと統合するためのインターフェースを提供する。これにより、ChatOps、監視システム、デプロイメントツールなどとの連携が可能になる。

**機能の利用シーン**：
- ビルドステータスの監視・通知
- ジョブ情報の取得と一覧表示
- ビルド結果の外部システムへの連携
- 設定のエクスポート・インポート
- カスタムダッシュボードの構築
- CI/CD パイプラインの自動化

**主要な処理内容**：
1. リソースオブジェクトの XML/JSON/Python 形式へのシリアライズ
2. XPath による XML データの絞り込み
3. tree パラメータによるレスポンスの構造指定
4. depth パラメータによるネスト深度の制御
5. exclude パラメータによるフィールド除外
6. スキーマ生成（XSD）

**関連システム・外部連携**：
- Stapler: Web フレームワーク
- @Exported アノテーション: 公開フィールドの定義
- ModelBuilder: モデルのメタデータ管理
- SecureRequester: セキュリティ制御

**権限による制御**：API アクセスは Jenkins の認証・認可システムに統合されており、ユーザーの権限に応じてアクセス可能なリソースが制限される。JSONP やプリミティブ XPath 結果は SecureRequester による追加制御が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 65 | API情報 | 主画面 | REST API 使用方法の説明表示 |
| 11 | ジョブ詳細 | API連携 | ジョブ情報の API 提供 |
| 14 | ビルド詳細 | API連携 | ビルド情報の API 提供 |

## 機能種別

API / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| xpath | String | No | XML 結果をフィルタする XPath 式 | 有効な XPath 式 |
| wrapper | String | No | XPath 結果をラップする要素名 | 有効な XML 要素名 |
| tree | String | No | 取得するフィールドの指定 | 有効な tree 構文 |
| depth | int | No | ネストの深度（デフォルト 1） | 0 以上の整数 |
| exclude | String[] | No | 除外するフィールドの XPath | 有効な XPath 式 |
| jsonp | String | No | JSONP コールバック関数名 | 有効な JavaScript 関数名 |

### 入力データソース

- HTTP リクエストパラメータ
- URL パス（リソース識別）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| XML | application/xml | XML 形式のレスポンス |
| JSON | application/json | JSON 形式のレスポンス |
| Python | text/x-python | Python 形式のレスポンス |

### 出力先

- HTTP レスポンスボディ

## 処理フロー

### 処理シーケンス

```
1. API リクエストの受信
   └─ /api/xml, /api/json, /api/python へのアクセス

2. セキュリティヘッダーの設定
   └─ X-Jenkins, X-Jenkins-Session
   └─ X-Content-Type-Options: nosniff
   └─ X-Frame-Options: deny

3. モデルオブジェクトの取得
   └─ bean プロパティからリソースオブジェクト取得

4. レスポンス形式の決定
   └─ URL パスから Flavor を決定（XML/JSON/PYTHON）

5. シリアライズ処理
   └─ ModelBuilder で @Exported フィールドを抽出
   └─ TreePruner で出力範囲を制御

6. XPath/exclude 処理（XML の場合）
   └─ dom4j で XML をパース
   └─ XPath 式を適用

7. レスポンス出力
   └─ 適切な Content-Type 設定
   └─ シリアライズ結果を出力
```

### フローチャート

```mermaid
flowchart TD
    A[API リクエスト] --> B[セキュリティヘッダー設定]
    B --> C{出力形式}
    C -->|XML| D[doXml]
    C -->|JSON| E[doJson]
    C -->|Python| F[doPython]
    D --> G{xpath/exclude あり?}
    G -->|No| H[直接シリアライズ]
    G -->|Yes| I[XML パース・XPath 適用]
    I --> J{結果判定}
    J -->|単一要素| K[XML 出力]
    J -->|複数要素| L{wrapper あり?}
    J -->|要素なし| M[404 エラー]
    L -->|Yes| N[wrapper で囲んで出力]
    L -->|No| O[500 エラー]
    H --> P[レスポンス出力]
    E --> P
    F --> P
    K --> P
    N --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-65-01 | 認証必須 | API アクセスには認証が必要（Anonymous 許可の場合を除く） | 常時 |
| BR-65-02 | JSONP 制限 | JSONP は SecureRequester の許可が必要 | jsonp パラメータ指定時 |
| BR-65-03 | プリミティブ XPath 制限 | 単純な XPath 結果は SecureRequester の許可が必要 | xpath でプリミティブ値取得時 |
| BR-65-04 | wrapper 名検証 | wrapper は有効な XML 要素名である必要がある | wrapper パラメータ指定時 |
| BR-65-05 | XPath 複数結果 | XPath で複数要素がマッチした場合は wrapper 必須 | xpath 結果が複数の場合 |

### 計算ロジック

**tree パラメータの解析**:
- NamedPathPruner クラスで tree 構文を解析
- カンマ区切りでフィールドを指定
- ブラケット [] でネストを指定

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

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

該当なし（REST API はデータベースを直接操作しない、読み取り専用）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | Bad Request | wrapper 名が不正 | エラーメッセージを返却 |
| 403 | Forbidden | JSONP/プリミティブ XPath が許可されていない | エラーメッセージを返却 |
| 404 | Not Found | XPath 結果が空 | エラーメッセージを返却 |
| 500 | Internal Error | XPath 複数結果で wrapper なし | エラーメッセージを返却 |

### リトライ仕様

該当なし（API リクエストは即座に結果を返す）

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

該当なし

## パフォーマンス要件

- depth/tree パラメータで取得データを制限し、レスポンスサイズを最適化
- 大量のビルド履歴などは depth=0 や tree 指定を推奨

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

- X-Content-Type-Options: nosniff でコンテンツスニッフィング防止
- X-Frame-Options: deny でクリックジャッキング防止
- JSONP は明示的に許可された場合のみ有効
- XPath の関数呼び出しは FilteredFunctionContext で制限
- API トークンによる認証を推奨（パスワード直接使用は非推奨）

## 備考

- Api クラスは AbstractModelObject を継承
- 各モデルオブジェクトの getApi() メソッドで Api インスタンスを提供
- _api.jelly ビューでカスタム API ドキュメントを提供可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Api.java | `core/src/main/java/hudson/model/Api.java` | Api クラスの基本構造（81-89行目） |

**読解のコツ**: Api クラスは AbstractModelObject を継承し、bean プロパティで公開対象のオブジェクトを保持している。

#### Step 2: XML API を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Api.java | `core/src/main/java/hudson/model/Api.java` | doXml() メソッド（104-211行目） |

**主要処理フロー**:
1. **109行目**: setHeaders() でセキュリティヘッダー設定
2. **113-117行目**: xpath/exclude なしの場合は直接シリアライズ
3. **122-124行目**: TreePruner で出力範囲を制御
4. **130-184行目**: XPath/exclude 処理
5. **192-209行目**: 結果の出力

#### Step 3: JSON API を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Api.java | `core/src/main/java/hudson/model/Api.java` | doJson() メソッド（231-263行目） |

**主要処理フロー**:
- **257-259行目**: jsonp チェックと permit()
- **259行目**: serveExposedBean() でシリアライズ

#### Step 4: セキュリティヘッダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Api.java | `core/src/main/java/hudson/model/Api.java` | setHeaders() メソッド（308-315行目） |

**主要処理フロー**:
- **309行目**: X-Jenkins ヘッダー
- **310行目**: X-Jenkins-Session ヘッダー
- **312行目**: X-Content-Type-Options: nosniff
- **314行目**: X-Frame-Options: deny

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

```
Api 操作
    │
    ├─ doXml()
    │      ├─ setHeaders() (109行目)
    │      ├─ serveExposedBean() (115行目) [xpath/exclude なし]
    │      ├─ ModelBuilder.get() (122行目)
    │      ├─ TreePruner (123行目)
    │      ├─ SAXReader.read() (130行目)
    │      ├─ XPath.selectNodes() (136, 150行目)
    │      └─ XMLWriter.write() (209行目)
    │
    ├─ doJson()
    │      ├─ setHeaders() (258行目)
    │      ├─ permit() (257行目)
    │      └─ serveExposedBean() (259行目)
    │
    └─ doPython()
           ├─ setHeaders() (294行目)
           └─ serveExposedBean() (295行目)
```

### データフロー図

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

HTTP リクエスト ─────▶ Api.doXml/doJson/doPython
                              │
                              ▼
                       bean オブジェクト取得
                              │
                              ▼
                       ModelBuilder ───────────▶ @Exported フィールド抽出
                              │
                              ▼
                       TreePruner ─────────────▶ 出力範囲制御
                              │
                              ▼
                       Flavor.createDataWriter() ▶ XML/JSON/Python シリアライズ
                              │
                              ▼
XPath/exclude ────────▶ dom4j 処理 ────────────▶ フィルタリング
                              │
                              ▼
                       HTTP レスポンス ─────────▶ Content-Type 設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Api.java | `core/src/main/java/hudson/model/Api.java` | ソース | REST API の主要クラス |
| ModelBuilder.java | `stapler/.../ModelBuilder.java` | ソース | モデルメタデータ管理 |
| TreePruner.java | `stapler/.../TreePruner.java` | ソース | 出力範囲制御 |
| Flavor.java | `stapler/.../Flavor.java` | ソース | 出力形式定義 |
| SecureRequester.java | `core/src/main/java/jenkins/security/SecureRequester.java` | ソース | セキュリティ制御 |
| FilteredFunctionContext.java | `core/src/main/java/jenkins/util/xml/FilteredFunctionContext.java` | ソース | XPath 関数制限 |
