mcpField
A
api-design-patterns

api-design-patterns

github.com/nickcrew開発6686 回インストール19 週間前に更新
リポジトリ

api-design-patterns について

REST と GraphQL API を新規設計・改修する開発者向けの設計ガイドです。バージョニング、ページネーション、エラー処理、認証、サービス契約などのパターンを扱います。

主な機能

  1. 01リソース指向の REST 設計
  2. 02バージョニングと廃止方針
  3. 03ページネーションとエラー応答
  4. 04認証、キャッシュ、レート制限
  5. 05GraphQL のクエリとミューテーション

活用シーン

  1. 01REST または GraphQL API の設計
  2. 02マイクロサービス契約の標準化
  3. 03大規模データ向けページネーション
  4. 04エラーと応答形式の統一

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nickcrew/claude-cortex --skill api-design-patterns

インストール後、Claude Code で/api-design-patternsを入力して読み込まれたか確認します。

同梱ファイルreferences/design-process.mdvalidation/rubric.yaml

詳細

API 設計パターン

バージョニング、ページネーション、エラーハンドリング、認証、サービスコントラクトに関する業界標準のパターンを用いて、スケーラブルで保守しやすい REST API と GraphQL API を設計するための専門的なガイダンスです。

このスキルを使用する場面

  • REST API または GraphQL API をゼロから設計するとき
  • スケーラビリティと一貫性を高めるために既存の API をリファクタリングするとき
  • マイクロサービスアーキテクチャのサービスコントラクトを定義するとき
  • API の進化に対応するバージョニング戦略を実装するとき
  • サービス間でエラーハンドリングとレスポンス形式を標準化するとき
  • 大規模なデータセット向けのページネーションを設計するとき
  • HATEOAS またはハイパーメディア駆動型 API を実装するとき
  • API 仕様(OpenAPI、GraphQL Schema)を作成するとき

クイックリファレンス

トピックリファレンスを読み込む
設計プロセスskills/api-design-patterns/references/design-process.md

基本原則

1. リソース指向設計(REST)

URL はアクションではなくリソースを表します:

✓ GET    /users/123
✓ POST   /users
✓ PUT    /users/123
✓ DELETE /users/123

✗ GET    /getUser?id=123
✗ POST   /createUser
✗ POST   /deleteUser

HTTP メソッドを意味に沿って使用します:

  • GET:リソースを取得します。冪等で、キャッシュ可能です
  • POST:リソースを作成します。非冪等です
  • PUT:リソース全体を置き換えます。冪等です
  • PATCH:リソースを部分的に更新します。冪等です
  • DELETE:リソースを削除します。冪等です
2. 一貫した命名規則
Resources:        /users, /orders, /products (plural nouns)
Nested:           /users/123/orders
Collections:      /users?status=active&page=2
Sub-resources:    /users/123/settings
Actions (rare):   /users/123/activate (POST)
3. HTTP ステータスコード

成功:

  • 200 OK:GET、PUT、PATCH に対する標準レスポンス
  • 201 Created:リソースが作成されました(POST)。Location ヘッダーを返します
  • 202 Accepted:非同期処理が開始されました
  • 204 No Content:レスポンスボディのない成功(DELETE)

クライアントエラー:

  • 400 Bad Request:構文が無効、または検証に失敗しました
  • 401 Unauthorized:認証が必要、または認証に失敗しました
  • 403 Forbidden:認証済みですが、権限が不十分です
  • 404 Not Found:リソースが存在しません
  • 409 Conflict:状態が競合しています(重複、バージョンの不一致)
  • 422 Unprocessable Entity:意味的な検証に失敗しました
  • 429 Too Many Requests:レート制限を超えました

サーバーエラー:

  • 500 Internal Server Error:予期しないサーバー障害
  • 502 Bad Gateway:上流サービスの障害
  • 503 Service Unavailable:一時的な過負荷またはメンテナンス
  • 504 Gateway Timeout:上流サービスのタイムアウト

バージョニング戦略

URI バージョニング(最も一般的)
GET /v1/users/123
GET /v2/users/123

Pros: Clear, easy to route, browser-testable
Cons: URL proliferation, cache fragmentation
When: Public APIs, major breaking changes
ヘッダーバージョニング
GET /users/123
Accept: application/vnd.myapi.v2+json

Pros: Clean URLs, content negotiation
Cons: Harder to test, caching complexity
When: Internal APIs, minor version differences
クエリパラメータバージョニング
GET /users/123?version=2

Pros: Simple, backward compatible
Cons: Pollutes query space, inconsistent
When: Rare, legacy compatibility
非推奨化ヘッダー
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
Deprecation: true
Link: <https://api.example.com/v2/users/123>; rel="successor-version"

ページネーションパターン

オフセットベースのページネーション
GET /users?limit=20&offset=40

Response:
{
  "data": [...],
  "pagination": {
    "limit": 20,
    "offset": 40,
    "total": 1543
  },
  "links": {
    "next": "/users?limit=20&offset=60",
    "prev": "/users?limit=20&offset=20"
  }
}

Pros: Simple, predictable, supports total count
Cons: Inconsistent with concurrent writes, performance degrades
When: Small datasets, stable data, admin UIs
カーソルベースのページネーション
GET /users?limit=20&cursor=eyJpZCI6MTIzfQ

Response:
{
  "data": [...],
  "pagination": {
    "next_cursor": "eyJpZCI6MTQzfQ",
    "has_more": true
  },
  "links": {
    "next": "/users?limit=20&cursor=eyJpZCI6MTQzfQ"
  }
}

Pros: Consistent with writes, scalable, efficient
Cons: No total count, can't jump to arbitrary page
When: Large datasets, real-time feeds, infinite scroll
キーセットページネーション(シーク方式)
GET /users?limit=20&after_id=123&created_after=2024-01-01T00:00:00Z

Pros: Most performant, index-friendly
Cons: Requires sortable field, complex queries
When: Very large datasets, time-series data

エラーレスポンス形式

標準エラースキーマ
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      {
        "field": "email",
        "code": "INVALID_FORMAT",
        "message": "Email format is invalid"
      },
      {
        "field": "age",
        "code": "OUT_OF_RANGE",
        "message": "Age must be between 18 and 120"
      }
    ],
    "request_id": "req_a3f7c9b2",
    "timestamp": "2024-01-15T10:30:00Z",
    "documentation_url": "https://docs.api.com/errors/VALIDATION_ERROR"
  }
}
エラーコードのパターン
Format: CATEGORY_SPECIFIC_REASON

Authentication:
- AUTH_MISSING_TOKEN
- AUTH_INVALID_TOKEN
- AUTH_EXPIRED_TOKEN

Authorization:
- AUTHZ_INSUFFICIENT_PERMISSIONS
- AUTHZ_RESOURCE_FORBIDDEN

Validation:
- VALIDATION_MISSING_FIELD
- VALIDATION_INVALID_FORMAT
- VALIDATION_OUT_OF_RANGE

Business Logic:
- BUSINESS_DUPLICATE_EMAIL
- BUSINESS_INSUFFICIENT_BALANCE
- BUSINESS_OPERATION_NOT_ALLOWED

System:
- SYSTEM_INTERNAL_ERROR
- SYSTEM_SERVICE_UNAVAILABLE
- SYSTEM_RATE_LIMIT_EXCEEDED

フィルタリングと検索

フィルタリング用クエリパラメータ
GET /users?status=active&role=admin&created_after=2024-01-01

GET /users?search=john&fields=name,email

GET /users?sort=-created_at,name  # - prefix for descending
複雑なフィルタリング(FIQL/RSQL)
GET /users?filter=status==active;role==admin,role==moderator
               # AND between semicolons, OR between commas

GET /products?filter=price>100;price<500;category==electronics
全文検索
GET /users?q=john+smith&fields=name,bio,company

Response includes relevance scoring:
{
  "data": [
    {
      "id": 123,
      "name": "John Smith",
      "_score": 0.95
    }
  ]
}

フィールド選択(スパースフィールドセット)

GET /users/123?fields=id,name,email

Response:
{
  "id": 123,
  "name": "John Doe",
  "email": "[email protected]"
}

# Nested resources
GET /users/123?fields=id,name,profile(avatar,bio)

Benefits:
- Reduced payload size
- Faster response times
- Lower bandwidth consumption
- Better mobile performance

HATEOAS(ハイパーメディア)

HAL(ハイパーテキストアプリケーション言語)
{
  "id": 123,
  "name": "John Doe",
  "email": "[email protected]",
  "_links": {
    "self": { "href": "/users/123" },
    "orders": { "href": "/users/123/orders" },
    "update": { "href": "/users/123", "method": "PUT" },
    "delete": { "href": "/users/123", "method": "DELETE" }
  },
  "_embedded": {
    "recent_orders": [
      {
        "id": 456,
        "total": 99.99,
        "_links": {
          "self": { "href": "/orders/456" }
        }
      }
    ]
  }
}
JSON:API 形式
{
  "data": {
    "type": "users",
    "id": "123",
    "attributes": {
      "name": "John Doe",
      "email": "[email protected]"
    },
    "relationships": {
      "orders": {
        "links": {
          "self": "/users/123/relationships/orders",
          "related": "/users/123/orders"
        }
      }
    },
    "links": {
      "self": "/users/123"
    }
  }
}

レート制限ヘッダー

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 742
X-RateLimit-Reset: 1705320000
Retry-After: 3600

# Standard (RFC 6585)
RateLimit-Limit: 1000
RateLimit-Remaining: 742
RateLimit-Reset: 3600

認証パターン

ベアラートークン(OAuth 2.0、JWT)
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Pros: Stateless, scalable, standard
Cons: Token size, revocation complexity
When: Modern APIs, microservices
API キー
X-API-Key: ak_live_a3f7c9b2d8e1f4g6h9

Pros: Simple, server-side management
Cons: Less secure, harder to scope
When: Internal services, admin APIs
Basic 認証
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

Pros: Simple, built-in browser support
Cons: Credentials in every request
When: Internal tools, development only

冪等性

冪等性キー(POST)
POST /payments
Idempotency-Key: a3f7c9b2-d8e1-4f6g-h9i0-j1k2l3m4n5o6
Content-Type: application/json

{
  "amount": 100.00,
  "currency": "USD",
  "description": "Payment for order #123"
}

# Server stores key + response for 24 hours
# Duplicate requests return cached response with 200 OK
自然な冪等性
PUT /users/123          # Always idempotent
DELETE /users/123       # Idempotent (404 on repeat)
POST /users/123/follow  # Use PUT for idempotency

キャッシュ戦略

ETag(条件付きリクエスト)
# Initial request
GET /users/123
ETag: "a3f7c9b2"

# Subsequent request
GET /users/123
If-None-Match: "a3f7c9b2"

# Response if unchanged:
304 Not Modified
Cache-Control ヘッダー
# Never cache
Cache-Control: no-store

# Cache for 1 hour, revalidate
Cache-Control: max-age=3600, must-revalidate

# Cache forever (immutable)
Cache-Control: public, max-age=31536000, immutable

GraphQL パターン

クエリ構造
query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
    orders(first: 10) {
      edges {
        node {
          id
          total
          status
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}
エラーハンドリング
{
  "data": {
    "user": null
  },
  "errors": [
    {
      "message": "User not found",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["user"],
      "extensions": {
        "code": "NOT_FOUND",
        "userId": "123"
      }
    }
  ]
}
ミューテーションパターン
mutation CreateUser($input: CreateUserInput!) {
  createUser(input: $input) {
    user {
      id
      name
      email
    }
    errors {
      field
      message
    }
  }
}

ベストプラクティスのまとめ

  1. 一貫性:すべてのエンドポイントで規約に従います
  2. バージョニング:初日から非推奨化戦略を計画します
  3. ドキュメント:OpenAPI/GraphQL スキーマを使用し、最新の状態に保ちます
  4. エラーハンドリング:コード付きの、詳細で対処可能なエラーメッセージを使用します
  5. セキュリティ:常に HTTPS を使用し、入力を検証して、レート制限を設けます
  6. パフォーマンス:キャッシュ、ページネーション、フィールド選択を実装します
  7. モニタリング:リクエスト ID を記録し、レイテンシとエラー率を追跡します
  8. 後方互換性:バージョン内では追加的な変更のみを行います
  9. テスト:コントラクトテスト、統合テスト、負荷テストを実施します
  10. ドキュメント:インタラクティブなドキュメント(Swagger UI、GraphQL Playground)を用意します

避けるべきアンチパターン

  1. おしゃべりな API:往復通信が多すぎます(バッチ処理や GraphQL を使用します)
  2. 過剰なデータ取得:不要なデータを返します(フィールド選択を使用します)
  3. データ取得不足:複数回の呼び出しが必要になります(includes/embeds を使用します)
  4. 実装の漏えい:API でデータベース構造を公開します
  5. 不十分なエラーメッセージ:詳細のない汎用的なエラーです
  6. 破壊的変更:バージョン管理せずに既存のフィールドを変更します
  7. レート制限がない:リソースの枯渇を許します
  8. ドキュメントの不足:エンドポイントやパラメーターが文書化されていません
  9. 命名の不統一:エンドポイント間で規則が統一されていません
  10. HTTP セマンティクスの無視:ステータスコードやメソッドを誤用します

リソース

コメント