Web api design
Web/HTTP API design practices from Stripe and REST guidelines: idempotency keys, pagination, versioning, object IDs, error payloads, resource-oriented URLs. Use when designing or implementing HTTP endpoints, REST APIs, or webhooks, or when the user says API設計, エンドポイント, REST API, Webhook. Not for internal module/class interfaces (use deep-module-design).From its SKILL.md
npx -y skills add goonobu-dot/dev-skills-library --skill web-api-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.6 KB, ~3.1k tokens by cl100k_base, as published. Nobody here has run it
Web API Design
HTTPで公開するAPI(REST/Webhook)を設計・実装するときに適用する実行知識。 「開発者を顧客として扱う」という前提に立ち、後方互換性・冪等性・可読性を最初から作り込む。内部モジュールのインターフェース設計は対象外(deep-module-designを使う)。
適用手順
1. リソース設計(着手時に必ず確認)
- URLは名詞・複数形・ケバブケースにする(例:
/user-profiles/{id},/orders)。動詞をURLに含めない(/getUserではなくGET /users/{id})。 - 操作はHTTPメソッドで表現する:一覧・取得=GET、作成=POST、全体更新=PUT、部分更新=PATCH、削除=DELETE。
- ネストは2階層までに抑える(
/orders/{id}/itemsはOK、/users/{id}/orders/{id}/items/{id}/...のような深いネストは避け、トップレベルリソース+クエリパラメータに切り替える)。 - レスポンスのフィールド名・大文字小文字規則をAPI全体で統一する(camelCase かsnake_caseかを最初に決めて混在させない)。
2. ID設計
- すべてのリソースIDに意味のあるプレフィックスを付ける(例:
usr_,ord_,evt_)。実装コストはほぼゼロで、ログ・デバッグ時にどのリソース種別か即座に判別できる。 - 連番の内部DB IDをそのまま外部公開しない。推測可能な連番は列挙攻撃・情報漏洩のリスクになる(ランダム性のあるID、またはULID/UUIDにプレフィックスを付与する)。
- IDは一度発行したら不変にする。リソースの属性変更でIDを変えない。
3. 冪等性(副作用のあるエンドポイント全てで検討)
- POST等の作成・課金・送信系エンドポイントには、クライアントが指定する冪等性キー(
Idempotency-Keyヘッダ)を受け付ける設計にする。 - サーバー側は同一キーでの再送を検知し、実処理を再実行せず前回と同じレスポンスを返す。
- 冪等性キーの保存期間(例: 24時間)を決め、期限切れ後は新規リクエストとして扱う。
- ネットワークリトライ・二重クリックなど「同じリクエストが複数回届く」ことを前提に設計する。冪等性を後付けするのは高コストなので、副作用のあるエンドポイントは最初から組み込む。
4. ページネーション
- 一覧取得APIはオフセット方式(
?page=2)ではなくカーソル方式(?after=xxx&limit=50)を優先する。オフセット方式はデータ追加・削除時に結果がずれ、大きなオフセットでDB性能が劣化する。 - レスポンスに次ページの有無・カーソル値・(可能なら)総件数を含める。
limitの上限をサーバー側で強制し、クライアント指定値をそのまま信用しない。
5. バージョニングと後方互換性
- 破壊的変更が必要になったら、既存クライアントを壊さない形で新バージョンを追加する(URLパス
/v2/またはAPIバージョン日付ヘッダ方式のいずれかをプロジェクトで統一する)。 - 「破壊的変更」の定義を明文化する:フィールド削除・型変更・必須化・既存の意味変更は破壊的、フィールド追加・新エンドポイント追加は非破壊的。
- 非推奨化する場合は猶予期間と告知手段(レスポンスヘッダの
Deprecation、変更履歴)を用意してから撤去する。
6. エラーレスポンス設計
- エラーは構造化されたペイロードで返す。最低限
code(機械可読な識別子)、message(人間可読な説明)、可能ならdetails(どのフィールドが問題か)を含める。 - HTTPステータスコードは標準的な意味に従う(400=クライアント起因の入力不正、401=未認証、403=権限不足、404=リソース不在、409=競合、422=意味的検証エラー、429=レート制限、5xx=サーバー起因)。すべて200やすべて500で返さない。
- エラーメッセージには対処のヒントを含める(例:「
emailフィールドの形式が不正です」であって「Bad Request」だけで終わらせない)。 - 内部実装の詳細(スタックトレース、SQL文、内部パス)をエラーレスポンスに含めない(情報漏洩対策。詳細はサーバーログ側に残す)。
7. Webhook設計(送信側になる場合)
- 受信側の冪等な処理を前提に、同一イベントが複数回配送されうることを明記する(配送保証は「少なくとも1回」が現実的)。
- イベントごとに一意のイベントID・タイムスタンプを付与し、受信側が重複排除できるようにする。
- 署名検証の仕組み(HMAC等)を用意し、受信側が送信元を検証できるようにする。
- リトライポリシー(指数バックオフ・最大試行回数)をドキュメント化する。
チェックリスト(実装前後で確認)
- URLは名詞・複数形・ケバブケース、動詞を含んでいない
- IDに意味のあるプレフィックスが付いている、連番DB IDを直接晒していない
- 副作用のあるエンドポイントに冪等性キーの受け口がある
- 一覧APIはカーソルベースのページネーションで、limit上限をサーバー側で強制している
- 破壊的変更が既存クライアントに影響しない形で導入されている(バージョニング方針に従っている)
- エラーレスポンスが構造化されており、ステータスコードが標準的な意味で使われている
- エラーメッセージに内部実装の詳細が漏れていない
- Webhookは重複配送・署名検証を前提に設計されている
アンチパターン集
| アンチパターン | なぜ問題か | 代わりにすること |
|---|---|---|
/getUserListのようなRPC風URL | HTTPメソッドの意味が失われ、一貫性がなくなる | GET /users にしてメソッドで操作を表現する |
| 内部の連番IDをそのまま公開 | 件数が推測でき、列挙攻撃・競合情報の漏洩につながる | プレフィックス付きランダムIDを発行する |
| POSTエンドポイントに冪等性キーがない | リトライ・二重送信で二重課金・二重作成が起きる | 作成・課金系には冪等性キーを最初から用意する |
| オフセットページネーションのみ提供 | データ変動時に結果が重複・欠落する、大きいoffsetで低速 | カーソルベースをデフォルトにする |
| すべてのエラーを200やHTTP 500で返す | クライアントがエラー種別で分岐できない | 意味に応じたステータスコードを返す |
| エラーメッセージにスタックトレース・SQL文を含める | 内部実装が漏洩し攻撃の手がかりになる | ユーザー向けメッセージと内部ログを分離する |
| 破壊的変更を既存バージョンに直接適用 | 既存クライアントが予告なく壊れる | 新バージョンを追加し、旧バージョンは猶予期間を設けて廃止する |
| Webhookが「1回だけ届く」前提で受信側を実装 | 実際は再送されうるため重複処理が起きる | イベントIDで冪等に処理する設計を受信側にも要求する |
出典
- Stripe Engineering, "Stripe's payments APIs: The first 10 years" (https://stripe.dev/blog/payment-api-design)
- Stripe, "Designing robust and predictable APIs with idempotency" (https://stripe.com/blog/idempotency)
- Stripe, "APIs as infrastructure: future-proofing Stripe with versioning" (https://stripe.com/blog/api-versioning)
- elsewhencode/project-guidelines (MIT License) — REST API設計規約部分
- John Ousterhout, A Philosophy of Software Design(深いモジュールの考え方をAPI設計に援用)
- 上記はいずれも要約・手順化したものであり、原文からの引用ではない。
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.