LESSON 30分

ストーリー

高橋アーキテクト
REST APIの設計には”成熟度”がある

高橋アーキテクトが4段階のピラミッドを描いた。

高橋アーキテクト
Leonard Richardson が提唱した成熟度モデルだ。Level 0 から Level 3 まであって、レベルが上がるほど”RESTらしい”APIになる
あなた
Level 3 のHATEOASって何ですか?
高橋アーキテクト
API自身が”次に何ができるか”を教えてくれる仕組みだ。Webブラウザがリンクをたどってページを移動するように、APIもリンクをたどって操作を発見できるようにする

リチャードソン成熟度モデル

4つのレベル

Level 3: ハイパーメディア制御(HATEOAS)

Level 2: HTTPメソッドの活用

Level 1: リソースの導入

Level 0: 単一URI・単一メソッド

Level 0: The Swamp of POX

// すべてのリクエストを単一のエンドポイントに送る
POST /api
Body: { "action": "getUser", "userId": 123 }

POST /api
Body: { "action": "createUser", "name": "田中" }

POST /api
Body: { "action": "deleteUser", "userId": 123 }

// 問題点:
// - HTTPメソッドの意味を無視(すべてPOST)
// - URLがリソースを表していない
// - 実質的にRPCスタイル

Level 1: リソースの導入

// リソースごとにURLを分離
POST /api/users
Body: { "action": "get", "userId": 123 }

POST /api/users
Body: { "action": "create", "name": "田中" }

POST /api/orders
Body: { "action": "get", "orderId": 456 }

// 改善点: URLがリソースを識別する
// 残る問題: すべてPOST、操作をBodyで指定

Level 2: HTTPメソッドの活用

// HTTPメソッドで操作を表現(多くのREST APIがこのレベル)
GET    /api/v1/users/123        // 200 OK
POST   /api/v1/users            // 201 Created
PUT    /api/v1/users/123        // 200 OK
DELETE /api/v1/users/123        // 204 No Content

// 改善点: HTTPの意味論を正しく使っている
// 残る問題: クライアントがURLを知っている必要がある

Level 3: HATEOAS

// HATEOAS = Hypermedia As The Engine Of Application State
// レスポンスに「次にできる操作」のリンクを含める

GET /api/v1/users/123
// レスポンス
{
  "data": {
    "id": "usr_123",
    "name": "田中太郎",
    "email": "tanaka@example.com",
    "status": "active"
  },
  "links": {
    "self": { "href": "/api/v1/users/123", "method": "GET" },
    "update": { "href": "/api/v1/users/123", "method": "PATCH" },
    "delete": { "href": "/api/v1/users/123", "method": "DELETE" },
    "orders": { "href": "/api/v1/users/123/orders", "method": "GET" },
    "deactivate": { "href": "/api/v1/users/123/deactivate", "method": "POST" }
  }
}

// ユーザーが非アクティブの場合、利用可能なアクションが変わる
GET /api/v1/users/456
{
  "data": {
    "id": "usr_456",
    "name": "鈴木花子",
    "status": "inactive"
  },
  "links": {
    "self": { "href": "/api/v1/users/456", "method": "GET" },
    "activate": { "href": "/api/v1/users/456/activate", "method": "POST" }
    // delete や update は非アクティブユーザーには提供しない
  }
}

HATEOASの実践

コレクションでのHATEOAS

GET /api/v1/users?page=2&perPage=20
{
  "data": [
    {
      "id": "usr_123",
      "name": "田中太郎",
      "links": {
        "self": { "href": "/api/v1/users/123" }
      }
    },
    {
      "id": "usr_124",
      "name": "鈴木花子",
      "links": {
        "self": { "href": "/api/v1/users/124" }
      }
    }
  ],
  "links": {
    "self": { "href": "/api/v1/users?page=2&perPage=20" },
    "first": { "href": "/api/v1/users?page=1&perPage=20" },
    "prev": { "href": "/api/v1/users?page=1&perPage=20" },
    "next": { "href": "/api/v1/users?page=3&perPage=20" },
    "last": { "href": "/api/v1/users?page=8&perPage=20" }
  },
  "meta": {
    "totalCount": 150,
    "currentPage": 2,
    "perPage": 20,
    "totalPages": 8
  }
}

ワークフローでのHATEOAS

// 注文ステータスに応じて利用可能な操作が変わる

// 注文直後
GET /api/v1/orders/456
{
  "data": { "id": "ord_456", "status": "pending" },
  "links": {
    "self": { "href": "/api/v1/orders/456" },
    "cancel": { "href": "/api/v1/orders/456/cancel", "method": "POST" },
    "pay": { "href": "/api/v1/orders/456/pay", "method": "POST" }
  }
}

// 支払い完了後
GET /api/v1/orders/456
{
  "data": { "id": "ord_456", "status": "paid" },
  "links": {
    "self": { "href": "/api/v1/orders/456" },
    "cancel": { "href": "/api/v1/orders/456/cancel", "method": "POST" },
    "shipment": { "href": "/api/v1/orders/456/shipment", "method": "GET" }
    // pay リンクは消えている(既に支払い済み)
  }
}

// 発送完了後
GET /api/v1/orders/456
{
  "data": { "id": "ord_456", "status": "shipped" },
  "links": {
    "self": { "href": "/api/v1/orders/456" },
    "tracking": { "href": "/api/v1/orders/456/tracking", "method": "GET" }
    // cancel リンクも消えている(発送後はキャンセル不可)
  }
}

HATEOASの現実的な採用

Level 2 vs Level 3

観点Level 2Level 3 (HATEOAS)
実装コスト低い高い
クライアントの複雑さURL をハードコードリンクをたどる実装が必要
柔軟性URL変更時にクライアントも変更サーバー側だけで変更可能
採用状況大多数のAPI一部の大規模API
推奨一般的なプロジェクト公開API、長期運用API

現実的なアプローチ

// 完全なHATEOASでなくても、部分的に取り入れる

// ページネーションリンク(よく使われる)
{
  "data": [...],
  "links": {
    "next": "/api/v1/users?cursor=abc123&limit=20",
    "prev": "/api/v1/users?cursor=xyz789&limit=20"
  }
}

// 関連リソースへのリンク
{
  "data": {
    "id": "ord_456",
    "userId": "usr_123",
    "links": {
      "user": "/api/v1/users/123",
      "items": "/api/v1/orders/456/items"
    }
  }
}

まとめ

レベル特徴採用度
Level 0単一URI、単一メソッドレガシーシステム
Level 1リソースごとにURI分離移行期のシステム
Level 2HTTPメソッドの正しい使用現在の主流
Level 3HATEOAS(ハイパーメディア)大規模公開API

チェックリスト

  • リチャードソン成熟度モデルの4レベルを説明できる
  • HATEOASの概念(レスポンスにリンクを含める)を理解した
  • Level 2 と Level 3 の違い・トレードオフを把握した
  • 現実的なHATEOAS採用パターンを理解した

次のステップへ

HATEOASとリチャードソン成熟度モデルを学びました。

次のセクションでは、APIの認証と認可の設計を学びます。 OAuth2、JWT、APIキー — 適切な認証方式の選択はAPI設計の重要な判断です。


推定読了時間: 30分