目次
この記事の内容
REST API は現代 Web 開発の標準ですが、その設計原則を正しく理解している開発者は多くありません。本記事では、REST の本質的な原則から、実戦で使える設計パターンまでを解説します。
REST の本質的な制約
REST(Representational State Transfer)は、アーキテクチャスタイルであり、以下の 6 つの制約を定義しています。
1. クライアント - サーバー(Client-Server)
関心の分離が核心です。
【クライアントの責任】
・ユーザーインターフェース
・ユーザー状態の管理
【サーバーの責任】
・データ保存
・ビジネスロジック
・認証・認可
メリット:
- クライアントとサーバーが独立して進化可能
- 移植性向上(Web、モバイル、デスクトップで共通 API)
2. ステートレス(Stateless)
各リクエストは独立しており、サーバーはクライアントの状態を保持しません。
// ❌ ステートフル(NG)
// 1 リクエスト目でユーザー情報を保存、2 リクエスト目で使用
POST /session
GET /profile // セッション状態に依存
// ✅ ステートレス(OK)
// 各リクエストに必要な情報をすべて含める
GET /profile
Authorization: Bearer eyJhbGc...
ステートレスの利点:
- スケーラビリティ向上(どのサーバーでも処理可能)
- 障害回復が容易(状態復活不要)
- 実装がシンプル
注意点: ステートレス = セッションなし、ではありません。認証状態はクライアント側で保持(JWT など)します。
3. キャッシュ(Cacheable)
レスポンスは、明示的にキャッシュ不可とされない限り、キャッシュ可能でなければなりません。
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=3600
ETag: "abc123"
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT
キャッシュディレクティブ:
| ディレクティブ | 意味 |
|---|---|
public | CDN 等でキャッシュ可能 |
private | ブラウザのみでキャッシュ |
no-cache | 必ずオリジンに検証 |
no-store | 一切キャッシュしない |
max-age=3600 | 3600 秒(1 時間)キャッシュ有効 |
4. 階層化システム(Layered System)
クライアントは、どの層に接続しているか意識しない設計です。
クライアント
│
▼
┌─────────────┐
│ ロードバランサー │
└─────────────┘
│
▼
┌─────────────┐
│ API ゲートウェイ │
└─────────────┘
│
▼
┌─────────────┐
│ 認証サービス │
└─────────────┘
│
▼
┌─────────────┐
│ ビジネスロジック │
└─────────────┘
各層は独立して配置・スケール可能です。
5. コードオンデマンド(Code on Demand)
オプションの制約。サーバーからクライアントにコード(JavaScript など)を送信します。
例:SPA の HTML/JS 配信、プラグインアーキテクチャ
6. 統一インターフェース(Uniform Interface)
REST の核心です。4 つのサブ制約から成り立ちます。
6.1 リソースの識別(Identification of Resources)
リソースはURI で一意に識別します。
✅ 良い例
GET /users/123
GET /articles/456/comments
❌ 悪い例(動詞を使っている)
GET /getUser?id=123
POST /createUser
6.2 表現によるリソース操作(Manipulation of Resources Through Representations)
リソースの**表現(JSON, XML 等)**を通じて操作します。
PUT /users/123
Content-Type: application/json
{
"name": "山田太郎",
"email": "taro@example.com"
}
6.3 自己記述的メッセージ(Self-descriptive Messages)
各メッセージは、処理に必要な情報をすべて含む必要があります。
✅ 良い例
GET /users/123
Host: api.example.com
Authorization: Bearer eyJhbGc...
Accept: application/json
❌ 悪い例(暗黙の依存)
GET /users/123
// Accept ヘッダーなし(サーバーが MIME タイプを推測)
// 認証情報なし(セッションに依存)
6.4 HATEOAS(Hypermedia as the Engine of Application State)
最も誤解されている原則です。
レスポンスに、次の可能な操作へのリンクを含めます。
{
"id": 123,
"name": "山田太郎",
"email": "taro@example.com",
"_links": {
"self": {
"href": "/users/123"
},
"update": {
"href": "/users/123",
"method": "PUT"
},
"delete": {
"href": "/users/123",
"method": "DELETE"
},
"orders": {
"href": "/users/123/orders"
}
}
}
HATEOAS の利点:
- クライアントは URI 構造を知らなくてよい
- API 変更が容易(リンク先を変えるだけ)
- 発見可能性向上
現実的な適用: 完全な HATEOAS 実装は稀ですが、重要な概念です。最低限、self リンクと主要な操作へのリンクは含めることを推奨します。
HTTP メソッドの正しい使い方
5 つの主要メソッド
| メソッド | 意味 | 冪等性 | 安全性 |
|---|---|---|---|
| GET | リソース取得 | ○ | ○ |
| POST | リソース作成 | × | × |
| PUT | リソース置換 | ○ | × |
| PATCH | リソース部分更新 | ○ | × |
| DELETE | リソース削除 | ○ | × |
冪等性(Idempotency)
**「同じ操作を複数回実行しても、結果が同じ」**性質です。
GET /users/123 → 1 回でも 100 回でも同じ結果
DELETE /users/123 → 1 回目:削除、2 回目:404(状態変化なし)
PUT /users/123 → 1 回でも 100 回でも同じ状態
POST /users → 1 回:1 ユーザー作成、2 回:2 ユーザー作成(冪等でない)
重要性: 冪等なメソッドは、ネットワーク障害時のリトライが安全です。
メソッドの選択ガイド
【新規作成】
・コレクションに追加 → POST
POST /users
【完全置換】
・リソース全体を更新 → PUT
PUT /users/123
{ "name": "新しい名前", "email": "new@example.com" }
// 全フィールドを送信(一部省略は NG)
【部分更新】
・一部フィールドのみ更新 → PATCH
PATCH /users/123
{ "email": "new@example.com" }
// email だけ更新(name は変更なし)
【削除】
・リソースを削除 → DELETE
DELETE /users/123
URI 設計のベストプラクティス
1. リソースは名詞で表現
✅ 良い
GET /users
GET /articles/123/comments
❌ 悪い
GET /getUsers
POST /createArticle
2. コレクションは複数形
✅ 良い
/users // ユーザー一覧
/users/123 // ユーザー 123
❌ 悪い(一貫性なし)
/user
/user/123
3. ネストは最大 2 段まで
✅ 良い(1 段)
/users/123/orders
✅ 許容(2 段)
/users/123/orders/456/items
❌ 悪い(3 段以上)
/users/123/orders/456/items/789/details
深くネストする場合は、フラットに:
✅ リファクタ後
/orders/456/items
4. クエリパラメータはフィルタ・ソート・ページネーション
✅ 良い例
GET /users?role=admin&status=active
GET /articles?sort=-created_at&page=2&limit=20
GET /products?category=electronics&min_price=1000
5. バージョニングは URI またはヘッダー
【URI バージョニング】(推奨、簡単)
GET /api/v1/users
GET /api/v2/users
【ヘッダーバージョニング】(洗練されているが複雑)
GET /users
Accept: application/vnd.example.v1+json
ステータスコードの正しい使い方
主要なステータスコード
| コード | 意味 | 使用場面 |
|---|---|---|
| 200 OK | 成功 | GET, PUT, PATCH |
| 201 Created | 作成完了 | POST 成功 |
| 204 No Content | 成功(ボディなし) | DELETE 成功 |
| 400 Bad Request | 不正なリクエスト | バリデーションエラー |
| 401 Unauthorized | 認証未実施 | 認証情報なし |
| 403 Forbidden | 権限なし | 認可エラー |
| 404 Not Found | リソースなし | 存在しない ID |
| 409 Conflict | 競合 | 重複データ |
| 422 Unprocessable Entity | バリデーションエラー | 形式は OK が意味エラー |
| 429 Too Many Requests | レート制限 | 過多なリクエスト |
| 500 Internal Server Error | サーバーエラー | 予期せぬ例外 |
エラーレスポンスの形式
{
"error": {
"code": "VALIDATION_ERROR",
"message": "入力値が無効です",
"details": [
{
"field": "email",
"message": "無効なメールアドレス形式です"
},
{
"field": "password",
"message": "パスワードは 8 文字以上で指定してください"
}
],
"documentation_url": "https://docs.example.com/errors/validation"
}
}
ページネーション設計
カーソルベース(推奨)
GET /users?cursor=eyJpZCI6MTAwfQ&limit=20
レスポンス:
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6MTIwfQ",
"has_more": true
}
}
メリット: 大量データでも安定したパフォーマンス
オフセットベース(簡易)
GET /users?offset=100&limit=20
レスポンス:
{
"data": [...],
"pagination": {
"total": 1000,
"offset": 100,
"limit": 20,
"has_more": true
}
}
デメリット: 深いページでパフォーマンス低下
実践的 API 設計チェックリスト
設計原則
- ステートレス設計になっている
- リソース指向の URI 設計
- 適切な HTTP メソッド使用
- 冪等性を考慮
- HATEOAS リンクを含める(可能であれば)
URI 設計
- 名詞を使用(動詞不使用)
- 複数形で一貫性
- ネストは最大 2 段
- クエリパラメータはフィルタ・ソート・ページネーション
- バージョニング方針を決定
レスポンス
- 適切なステータスコード
- 一貫したエラーフォーマット
- ページネーション情報を含める
- キャッシュヘッダーを設定
セキュリティ
- HTTPS 必須
- 認証・認可を実装
- レート制限を設定
- 機密情報をログに出力しない
ドキュメント
- OpenAPI/Swagger で仕様定義
- 各エンドポイントの使用例
- エラーコード一覧
- 変更履歴(チェンジログ)
まとめ
REST API 設計の核心:
- ステートレス——各リクエストを独立して処理
- リソース指向——URI は名詞、複数形で統一
- HTTP メソッドの正しい使用——GET/POST/PUT/PATCH/DELETE
- 冪等性の理解——リトライ安全な設計
- HATEOAS——リンクで可能な操作を示す(理想)
「REST は規則ではなく、思考の枠組み」
完全な REST 準拠よりも、一貫性のある設計を心がけましょう。
参考資料
- Fielding, R. T. (2000). “Architectural Styles and the Design of Network-based Software Architectures”
- Richardson Maturity Model
- OpenAPI Specification
- Google API Design Guide
- Stripe API Reference(優れた実例)
免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。