Claudeに90%書いてもらいつつ、シンプルにした好みのREST API ガイドライン

マークダウンが反映されなくてつらいけど面倒だからそのまま貼る。

———

# REST API設計規約

## 1. 基本原則

### 1.1 RESTの基本原則に従う

- リソース指向設計

- ステートレス通信

- 統一インターフェース

- 自己記述型メッセージ

### 1.2 シンプルさを重視する

- 複雑な設計よりもシンプルな設計を優先する

- 直感的で理解しやすいAPIを設計する

## 2. リソース設計

### 2.1 リソース名

- 名詞を使用し、複数形で表現する(例: `/users`, `/products`)

- リソース名は小文字のみ使用し、ハイフン(-)で単語を区切る

- 特殊文字やスペースは使用しない

### 2.2 リソースの階層

- 親子関係がある場合は階層構造で表現する(例: `/users/{userId}/orders`)

- 階層は最大で3〜4レベルまでに制限する

### 2.3 リソースの識別

- リソースIDはURIパスで指定する(例: `/users/{userId}`)

- IDはシステム内で一意であること

## 3. HTTP動詞の利用

### 3.1 標準的なHTTP動詞の使用

| 動詞 | 用途 | 例 |

|———|———|———|

| GET | リソースの取得 | `GET /users/{userId}` |

| POST | リソースの作成 | `POST /users` |

| PUT | リソースの完全更新 | `PUT /users/{userId}` |

| PATCH | リソースの部分更新 | `PATCH /users/{userId}` |

| DELETE | リソースの削除 | `DELETE /users/{userId}` |

#### PUTとPATCHの違い

- **PUT**: リソース全体を置き換える完全更新。クライアントはリソースの全フィールドを送信する必要がある。送信されなかったフィールドは初期値または null にリセットされる。

- **PATCH**: リソースの一部のみを更新する部分更新。クライアントは変更したいフィールドのみを送信すればよい。送信されなかったフィールドは変更されない。

- 例: ユーザーの名前だけを更新する場合

### 3.2 動詞の安全性と冪等性

- GETは安全であり冪等である(何度実行しても同じ結果、副作用なし)

- PUTとDELETEは冪等である(何度実行しても同じ状態になる)

- POSTは安全でも冪等でもない

## 4. クエリパラメータ

### 4.1 フィルタリング

- フィルタリングはクエリパラメータで行う(例: `/users?status=active`)

- 複数の条件はアンパサンド(&)で連結する(例: `/users?status=active&role=admin`)

### 4.2 ソート

- ソートはsortパラメータで指定する(例: `/users?sort=lastName`)

- 昇順/降順はプレフィックス+/-で指定する(例: `/users?sort=-createdAt`)

### 4.3 ページネーション

- トークンベースのページネーションを使用する

- 例: `/users?limit=20&page_token=eyJvZmZzZXQiOjQwfQ==`

- 次ページのトークンはレスポンスに含める

- デフォルト値と最大値を設定する

### 4.4 フィールド選択

- 取得するフィールドをfieldsパラメータで指定できる(例: `/users?fields=id,name,email`)

- フィールド選択はオプション機能であり、実装は必須ではない

## 5. レスポンス設計

### 5.1 ステータスコード

| コード | 説明 | 使用例 |

|————|———|————|

| 200 | OK | リクエスト成功(GET, PUT, PATCH) |

| 201 | Created | リソース作成成功(POST) |

| 204 | No Content | リクエスト成功、返すコンテンツなし(DELETE) |

| 400 | Bad Request | リクエスト形式が不正 |

| 401 | Unauthorized | 認証が必要 |

| 403 | Forbidden | 認証済みだが権限がない |

| 404 | Not Found | リソースが存在しない |

| 429 | Too Many Requests | レート制限超過 |

| 500 | Internal Server Error | サーバー内部エラー |

### 5.2 エラーレスポンス形式

```json

{

“error”: {

"code": "RESOURCE_NOT_FOUND",

"message": "指定されたユーザーは存在しません"

}

}

```

### 5.3 成功レスポンス形式

- 単一リソース

```json

{

“id”: “user123”,

“name”: “山田太郎”,

“email”: “yamada@example.com”,

“createdAt”: “2023-01-15T12:00:00Z”

}

```

- リソースコレクション

```json

{

“items”: [

{

  "id": "user123",

  "name": "山田太郎"

},

{

  "id": "user456",

  "name": "佐藤次郎"

}

],

“metadata”: {

"totalCount": 2500,

"returnedCount": 2,

"limit": 2,

"nextPageToken": "eyJvZmZzZXQiOjJ9"

}

}

```

### 5.4 POSTメソッドのレスポンス規則

- リソース作成(Create)の場合:

```json

{

“id”: “user789”,

“name”: “鈴木花子”,

“email”: “suzuki@example.com”,

“createdAt”: “2023-01-15T12:00:00Z”

}

```

- アクション実行の場合:

## 6. バージョニング

### 6.1 バージョニング方式

- URIパスでバージョンを指定する(例: `/v1/users`)

- メジャーバージョンのみをURIに含める

### 6.2 後方互換性

- 既存のAPIに対する破壊的変更はしない

- 機能追加は後方互換性を保持する

- 破壊的変更が必要な場合は新しいバージョンを作成する

## 7. セキュリティ

### 7.1 認証・認可

- APIキーまたはOAuth 2.0を使用する

- 認証情報はHTTP Authorizationヘッダで送信する

- すべてのエンドポイントでTLSを使用する

### 7.2 レート制限

- APIアクセスにレート制限を設けることはオプションである

- レート制限を実装する場合、制限状態を以下のヘッダで通知する

### 7.3 入力バリデーション

- すべてのユーザー入力を検証する

- 入力検証エラーは400 Bad Requestで返す

- 詳細なエラーメッセージを提供する

## 8. パフォーマンスとキャッシング

### 8.1 キャッシュ制御

- Cache-Controlヘッダを適切に設定する

- ETagを利用して条件付きリクエストをサポートする

### 8.2 圧縮

- 大きなレスポンスはgzipで圧縮する

- Accept-Encodingヘッダで対応する圧縮形式を確認する

## 9. 日付と時刻

### 9.1 形式

- 日付と時刻はISO 8601形式を使用する(例: `2023-04-01T13:45:30Z`)

- タイムゾーンはUTCを使用し、末尾に「Z」を付ける

## 10. ドキュメント

### 10.1 API仕様

- OpenAPI(Swagger)仕様に従ってAPIをドキュメント化する

- 各エンドポイントの説明、パラメータ、レスポンスを詳細に記述する

## 12. 複雑な操作

### 12.1 一括操作

- 一括作成/更新はコレクションに対するPOST/PUTで行う

- レスポンスには各項目の処理結果を含める

### 12.2 非RESTful操作

- リソース指向で表現できない操作はカスタムアクションとして実装する

- コロン構文を使用する: `{リソース}:{Action}`

- 例: `/users/{userId}:reset-password`(POST)