mcpField
A
api-design

api-design

github.com/seb1n開発243138 回インストール13 週間前に更新
リポジトリ

api-design について

api-design は、AI エージェント向けに本番運用を想定した REST API の設計を支援するスキルです。リソース設計やエンドポイントの意味付けから、スキーマ、OpenAPI 文書、ページネーション、バージョン管理まで扱います。

主な機能

  1. 01リソースと関係の設計
  2. 02CRUD エンドポイントと HTTP の意味
  3. 03リクエスト・レスポンススキーマ設計
  4. 04ページネーション・絞り込み・ソート
  5. 05バージョン管理とコンテンツネゴシエーション
  6. 06OpenAPI 3.0 文書

活用シーン

  1. 01アプリケーション領域からの API 設計
  2. 02OpenAPI によるエンドポイントとスキーマの文書化
  3. 03一覧の絞り込みとページネーションの計画
  4. 04API バージョンとエラー規約の策定

インストール

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

$npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill api-design

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

詳細

API 設計

このスキルを使うと、AI エージェントは本番品質の RESTful API を設計できます。エージェントはリソースをモデル化し、適切な HTTP メソッドのセマンティクスに従ってエンドポイントを定義し、適切なステータスコードを選択し、ページネーションとバージョニングの戦略を実装して、OpenAPI ドキュメントを作成します。出力は、ステートレス性、統一インターフェース、リソースベースの URI など、REST の制約に従います。

ワークフロー

  1. リソースと関係を特定する: アプリケーションのドメインを分析し、名詞をリソース(例:ユーザー、タスク、コメント)として抽出します。リソース間の関係(一対多、多対多)を整理し、サブリソースと独立したコレクションのどちらが適切かを判断します。動詞ベースのエンドポイントは避けてください。リソースはアクションではなく、エンティティを表す必要があります。

  2. エンドポイントと HTTP メソッドを定義する: 各リソースについて、適切な HTTP メソッドを使って CRUD エンドポイントを定義します。取得には GET(安全、べき等)、作成には POST(べき等ではない)、全置換には PUT(べき等)、部分更新には PATCH(べき等)、削除には DELETE(べき等)を使用します。親との関係が強い場合は、親の下にサブリソースをネストします(例:/tasks/{id}/comments)。

  3. リクエストとレスポンスのスキーマを設計する: 各エンドポイントの JSON リクエストボディ、レスポンスペイロード、クエリパラメーターを定義します。フィールド名には snake_case または camelCase を一貫して使用します。必須フィールドと任意フィールド、データ型、検証制約を指定します。すべてのエンドポイントで使用する一貫したエラーレスポンス形式を設計します。

  4. ページネーション、フィルタリング、ソートを実装する: リストエンドポイントには、limit と offset(または cursor)のクエリパラメーターを使ったカーソルベースまたはオフセットベースのページネーションを追加します。クエリパラメーターによるフィルタリング(例:?status=active)と、sort および order パラメーターによるソートをサポートします。レスポンスボディに、合計件数や次/前のリンクなどのページネーションメタデータを含めます。

  5. バージョニングとコンテンツネゴシエーションを定義する: URI パス(/v1/tasks)、クエリパラメーター(?version=1)、Accept ヘッダー(Accept: application/vnd.api.v1+json)などから、バージョニング戦略を選択します。URI パスによるバージョニングが最も簡単で、最も一般的です。バージョン内で後方互換性を確保し、非推奨化のスケジュールを文書化します。

  6. OpenAPI ドキュメントを生成する: パス、スキーマ、セキュリティスキーム、リクエスト/レスポンスの例を含む、完全な OpenAPI 3.0 仕様を作成します。レスポンスのドキュメントに、レート制限ヘッダー(X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset)を含めます。

対応テクノロジー

  • 仕様形式: OpenAPI 3.0/3.1、JSON Schema、AsyncAPI(イベント駆動型拡張向け)
  • フレームワーク: Express.js、FastAPI、Django REST Framework、Spring Boot、Rails API
  • ドキュメントツール: Swagger UI、Redoc、Stoplight
  • テスト: Postman、Insomnia、REST Client(VS Code)、curl

使用方法

アプリケーションのドメイン、関係するエンティティ、ユーザーが実行する必要のある操作についての説明をエージェントに提供します。エージェントはエンドポイント定義、リクエスト/レスポンスのスキーマ、OpenAPI 仕様を作成します。特定のエンドポイントの変更、ページネーションの追加、エラー形式の調整を依頼して、繰り返し改善できます。

例

例 1:タスク管理 API(OpenAPI 仕様の抜粋)
openapi: 3.0.3
info:
  title: Task Management API
  version: 1.0.0
  description: RESTful API for managing tasks and projects.

servers:
  - url: https://api.example.com/v1

paths:
  /tasks:
    get:
      summary: List all tasks
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [pending, in_progress, done]
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: cursor
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Paginated list of tasks
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
            X-RateLimit-Remaining:
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Task"
                  pagination:
                    $ref: "#/components/schemas/CursorPagination"
    post:
      summary: Create a new task
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TaskCreate"
      responses:
        "201":
          description: Task created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /tasks/{taskId}:
    get:
      summary: Get a task by ID
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Task details
        "404":
          description: Task not found

components:
  schemas:
    Task:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type: string
        status:
          type: string
          enum: [pending, in_progress, done]
        created_at:
          type: string
          format: date-time
    TaskCreate:
      type: object
      required: [title]
      properties:
        title:
          type: string
          maxLength: 255
        description:
          type: string
        assignee_id:
          type: string
          format: uuid
    CursorPagination:
      type: object
      properties:
        next_cursor:
          type: string
          nullable: true
        has_more:
          type: boolean
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  reason:
                    type: string
例 2:一貫したエラーレスポンス形式
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed.",
    "details": [
      {
        "field": "title",
        "reason": "Title is required and cannot be empty."
      },
      {
        "field": "assignee_id",
        "reason": "Must be a valid UUID."
      }
    ],
    "request_id": "req_abc123",
    "documentation_url": "https://api.example.com/docs/errors#VALIDATION_ERROR"
  }
}

すべてのエンドポイントで一貫して使用する標準エラーコード:

HTTP ステータスエラーコード意味
400BAD_REQUEST不正なリクエスト構文
401UNAUTHORIZED認証情報がない、または無効
403FORBIDDEN認証済みだが、権限が不足している
404NOT_FOUNDリソースが存在しない
409CONFLICTリソースの状態が競合している(例:重複)
422VALIDATION_ERRORセマンティック検証に失敗
429RATE_LIMITEDリクエストが多すぎる
500INTERNAL_ERROR予期しないサーバーエラー

ベストプラクティス

  • リソースパスには複数形の名詞を使用し(/task ではなく /tasks)、URI では動詞を避けます。CRUD に当てはまらないアクションには、サブリソースを使用します(例:POST /tasks/{id}/archive)。
  • Idempotency-Key ヘッダーを POST リクエストでサポートし、冪等性を確保します。 PUT と DELETE は本質的に冪等です。この動作を明確に説明してください。
  • すべてのレスポンスにレート制限ヘッダー(X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset)を含め、クライアントがリクエスト頻度を自ら調整できるようにします。
  • レスポンスに HATEOAS リンクを使用して、API の探索を可能にします。適切な場合は、self、next、prev と関連リソースの URI を含む _links を追加します。
  • v1 しかなくても、最初からバージョン管理を行います。 これにより、後の困難な移行を防げます。古いバージョンは Sunset ヘッダーと Deprecation ヘッダーを使用して非推奨にします。
  • 201 Created のレスポンスでは Location ヘッダーを返し、新しく作成されたリソースの URI を指定します。

エッジケース

  • 空のコレクション: 404 ではなく、空の data 配列と has_more: false を含む 200 OK を返します。
  • 削除されたリソース: 完全に削除されたリソースには 404 Not Found を返します。論理削除されたリソースには、リソースが削除された日時のメタデータを含む 410 Gone を返します。
  • 同時更新: 楽観的同時実行制御には ETag ヘッダーと If-Match ヘッダーを使用します。クライアントが最後に取得してからリソースが変更されている場合は、412 Precondition Failed を返します。
  • バッチ操作での部分的な失敗: 項目ごとのステータスコードを含む 207 Multi-Status を返し、クライアントがどの項目が成功し、どの項目が失敗したかを把握できるようにします。
  • 末尾のスラッシュ: /tasks/ と /tasks が同じハンドラーに処理されるように正規化します。正規形式を1つに統一する場合は、301 リダイレクトを返します。
  • 不明なクエリパラメーター: 不明なパラメーターを黙って無視するか、明確なメッセージとともに 400 を返します。どちらかの方法を選び、一貫して適用してください。

コメント