api-design について
api-design は、AI エージェント向けに本番運用を想定した REST API の設計を支援するスキルです。リソース設計やエンドポイントの意味付けから、スキーマ、OpenAPI 文書、ページネーション、バージョン管理まで扱います。
主な機能
- 01リソースと関係の設計
- 02CRUD エンドポイントと HTTP の意味
- 03リクエスト・レスポンススキーマ設計
- 04ページネーション・絞り込み・ソート
- 05バージョン管理とコンテンツネゴシエーション
- 06OpenAPI 3.0 文書
活用シーン
- 01アプリケーション領域からの API 設計
- 02OpenAPI によるエンドポイントとスキーマの文書化
- 03一覧の絞り込みとページネーションの計画
- 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 の制約に従います。
ワークフロー
-
リソースと関係を特定する: アプリケーションのドメインを分析し、名詞をリソース(例:ユーザー、タスク、コメント)として抽出します。リソース間の関係(一対多、多対多)を整理し、サブリソースと独立したコレクションのどちらが適切かを判断します。動詞ベースのエンドポイントは避けてください。リソースはアクションではなく、エンティティを表す必要があります。
-
エンドポイントと HTTP メソッドを定義する: 各リソースについて、適切な HTTP メソッドを使って CRUD エンドポイントを定義します。取得には GET(安全、べき等)、作成には POST(べき等ではない)、全置換には PUT(べき等)、部分更新には PATCH(べき等)、削除には DELETE(べき等)を使用します。親との関係が強い場合は、親の下にサブリソースをネストします(例:
/tasks/{id}/comments)。 -
リクエストとレスポンスのスキーマを設計する: 各エンドポイントの JSON リクエストボディ、レスポンスペイロード、クエリパラメーターを定義します。フィールド名には snake_case または camelCase を一貫して使用します。必須フィールドと任意フィールド、データ型、検証制約を指定します。すべてのエンドポイントで使用する一貫したエラーレスポンス形式を設計します。
-
ページネーション、フィルタリング、ソートを実装する: リストエンドポイントには、
limitとoffset(またはcursor)のクエリパラメーターを使ったカーソルベースまたはオフセットベースのページネーションを追加します。クエリパラメーターによるフィルタリング(例:?status=active)と、sortおよびorderパラメーターによるソートをサポートします。レスポンスボディに、合計件数や次/前のリンクなどのページネーションメタデータを含めます。 -
バージョニングとコンテンツネゴシエーションを定義する: URI パス(
/v1/tasks)、クエリパラメーター(?version=1)、Accept ヘッダー(Accept: application/vnd.api.v1+json)などから、バージョニング戦略を選択します。URI パスによるバージョニングが最も簡単で、最も一般的です。バージョン内で後方互換性を確保し、非推奨化のスケジュールを文書化します。 -
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 ステータス | エラーコード | 意味 |
|---|---|---|
| 400 | BAD_REQUEST | 不正なリクエスト構文 |
| 401 | UNAUTHORIZED | 認証情報がない、または無効 |
| 403 | FORBIDDEN | 認証済みだが、権限が不足している |
| 404 | NOT_FOUND | リソースが存在しない |
| 409 | CONFLICT | リソースの状態が競合している(例:重複) |
| 422 | VALIDATION_ERROR | セマンティック検証に失敗 |
| 429 | RATE_LIMITED | リクエストが多すぎる |
| 500 | INTERNAL_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を返します。どちらかの方法を選び、一貫して適用してください。