old-coder-api について
old-coder-apiは、HTTP/JSON APIを設計・レビューするエージェント向けスキルです。互換性、認可、再試行、ページネーション、運用リスクの確認項目と、レビュー結果の形式を示します。
主な機能
- 01HTTP/JSON契約の設計指針
- 02既存APIの互換性チェック
- 03認証と認可の確認項目
- 04冪等性とページネーションの指針
- 05APIレビュー結果の形式
活用シーン
- 01新しいHTTP/JSON APIの設計
- 02変更による互換性破壊の確認
- 03アクセス制御と再試行安全性のレビュー
- 04レート制限と大規模コレクションの評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ amazingang/ old-coder --skill old-coder-apiインストール後、Claude Code で/old-coder-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/breaking-changes.mdexamples.mdpatterns.md詳細
old-coder-api
Sean Goedecke の Everything I know about good API design(2025-08-24)に着想を得ています。
このスキルでは、HTTP/JSON の契約と運用性に関する懸念を扱います。互換性ルールは、JSON の利用者を前提としています。gRPC/protobuf、GraphQL、WebSockets、または別のプロトコルでは、トランスポートに依存しない原則を、そのプロトコル独自の互換性ルールと併せて適用してください。これは、アプリケーションセキュリティの全面的なレビューに代わるものではありません。
優れた API は退屈です。 API を作る人にとって、API は製品です。API を使う人にとっては、別の目的を達成するための道具です。利用者が目的ではなく API のことを考えるのに費やす時間は、すべて無駄です。興味を引く API は悪い API です。そうでなければ、もっと興味を引かないものにすれば、より良い API になります。
エージェントがデフォルトで陥りやすい失敗モードが 2 つあり、このスキルはその両方を防ぐためにあります。
- 独自仕様にする。 退屈でも慣例に沿った方法で十分なのに、巧妙で独自のインターフェースを作り出す。
- 壊す。 今の見た目を良くするためにフィールド名を変えたり、構造を変えたり、制約を厳しくしたりして、下流の呼び出し元をすべて気付かれないまま壊す。
old-coder との併用: 両方のスキルが適用される場合、このスキルは
HTTP/JSON の契約を担当し、old-coder はワークフローの順序、SPEC の承認、
ガントレット、および EVIDENCE を担当します。SPEC の承認前に Step 0 と
各ゲートを実施し、残った API の制約とリスクを SPEC に記載して、
ガントレットを通じて検証してください。実装を伴わないレビューのみの作業では、
開発ループを無理に作り出さず、このスキルのレビュー形式を使用してください。
Step 0 — 設計を始める前にスコープを確定する
ルートを書く前に、次の 3 つの問いに声に出して答えてください。
| 問い | 作業に影響する理由 |
|---|---|
| 公開 API か、内部 API か? すべての利用者向けにコードをリリースできますか? | 内部 API:破壊的変更を許容でき、複雑な認証も問題なく、エンジニア以外にとっての使いやすさは重要ではありません。公開 API:これらはどれも当てはまりません。 |
| 既存の API か、新規開発か? | 既存の場合 → references/breaking-changes.md を最初に実行してください。互換性は、以下のあらゆる改善に優先します。 |
| 製品のリソースモデルは、この API をサポートしていますか? | API 設計は、製品の基本的なリソースに沿うものです。リソースの設計に難がある場合(名前のないステートマシン、ジョブ内にしか存在しないレコード、モデル化されていない親子関係など)、どれほど慎重に設計しても API は使いにくくなります。取り繕わず、そのことを伝えてください。 |
Step 0 の誠実さのルール: 問題のある部分が基盤となるモデルに起因する場合は、そのことを明示し、モデルを修正することが本質的な選択肢だと提案してください。本来読み取り処理であるべきものにバックグラウンドジョブのポーリングインターフェースを後付けすると、最悪の API が生まれます。UI が隠している技術的制約が API ではあらわになり、利用者は本来知る必要のないシステムの詳細まで理解せざるを得なくなります。
ゲート
すべてのゲートを実施してください。検証済みの合格にのみ ✓ を使用し、検証済みの不合格には ✗ + 具体的な修正策 を使用してください。ゲートが本当に該当しない場合に限り N/A + 理由 を使用し、未検証のままの場合は ? + 理由 を使用してください。何も言わずに省略してはいけません。
1. ありきたりであること
知識のある利用者なら、ドキュメントを読む前にこのエンドポイントを推測できるべきです。
- リソースには、製品の名詞(
/issues、/projects、/users)を複数形で使い、安定したものにします。 - この API で確立されている慣例に従い、標準的な動詞とステータスコードを使います。一般的なクライアントエラーには
400を使い、コンテンツタイプと構文が有効でも、内容に含まれる指示を処理できない場合に限り422を使います。リソースが見つからない場合は404、レート制限時は429を使います。 - 標準的なフィールド名を使います:
id、created_at、next_page、url。この API の他の部分ですでに使われている名前に合わせます。外部の慣例と矛盾する場合は、外部の慣例より内部の一貫性を優先します。 - 理由がない限り、REST + JSON を使います。確立され、内部で一貫性のある HTTP RPC インターフェースも、ありきたりな設計にできます。REST の純粋さを求めて、リソースパスに改名してはいけません。HATEOAS や JSON と他の形式の比較を蒸し返す必要はありません。重要ではありません。
- **意外な点には、理由を一文で明記します。**一文で説明できない場合は、ありきたりな設計にします。
2. 既存の利用者を壊さない
既存のインターフェースに対する変更にのみ適用されます。全体の対応表はreferences/breaking-changes.mdを参照してください。
- 追加は問題ありません。新しいエンドポイント、新しい任意パラメーター、新しいレスポンスフィールドが該当します。利用者は未知のフィールドを無視することが前提です。
- フィールドの削除、名前の変更、型の変更、移動(
user.address→user.details.address)、列挙値の範囲の縮小、検証の厳格化は破壊的変更です。より整然としていても、行ってはいけません。HTTP のrefererヘッダーは誤記ですが、今もそのまま存在しています。 - 破壊的変更が本当に避けられない場合は、最後の手段としてバージョニングを行います。詳細はリファレンスを参照してください。
3. 認証:最も簡単で安全な方法を使いやすくする
サーバー間の連携の多くは、curlや20行程度のスクリプトから始まります。開発者向けのサーバー間 API では、シンプルでスコープを限定でき、失効可能な API キーをデフォルトにします。
- ブラウザーやモバイルのクライアント、ユーザーに委任されたアクセス、高い機密性のデータ、またはポリシーで必要とされる環境では、代わりに OAuth などの短命な方式、あるいは送信者制約付きの方式を使います。これらのクライアントに、長期間有効なベアラー認証情報を渡してはいけません。
- すべての認証情報の種類について、スコープ、ローテーション、失効、安全な転送手段、およびインシデント発生時に認証情報を特定または無効化する方法を定義します。
- 内部認証情報の使いやすさには適用されません。インフラストラクチャですでに提供されている仕組み(mTLS、ワークロード ID、サービス トークン)を使い、運用上の制御も確認します。
4. 認可:誰が、どのリソースに対して、何を実行できるかを制御する
認証は呼び出し元を特定しますが、アクションを認可するものではありません。各エンドポイントについて、アクター、アクション、リソース、テナント境界を特定します。
- 解決済みのリソースに対して、サーバー側で認可を強制します。認証済みのプリンシパルと照合せず、呼び出し元が指定した
tenant_id、所有者 ID、ロール、スコープを信頼してはいけません。 - リスト、検索、一括処理、エクスポート、ネストされたリソース、間接参照のパスにも同じチェックを適用します。データ取得後のフィルタリングは、認可の境界にはなりません。
- 意図的に匿名で公開する操作に限り、理由を一文で記せば適用対象外にできます。セキュリティに関わる変更では、これらの API ゲートに加えて、専任のセキュリティレビューを必須にします。
5. アクションを伴うすべての処理に冪等性を持たせる
500 やタイムアウトが発生しても、アクションが実行されたかどうかは呼び出し元には分かりません。冪等性キーがなければ、呼び出し元は処理が失われるか、重複して実行されるかのどちらかを選ばなければなりません。
- すでに冪等ではなく、新規作成、実行開始、または相対的な変更の適用を行うすべての処理で、冪等性キー(ヘッダーまたはパラメーター)を受け付けます。同じキーで再度呼び出された場合は、二重に処理せず、元の結果を返します。
- たまに重複するコストのほうが、導入の負担より低い低リスクの処理では、任意のままにしておきます。
- 重複が許されない処理(支払い、送金、投薬、取り消し不能な外部への副作用)では、冪等性キーまたは固有の操作 ID を必須とし、処理の実行と重複排除をアトミックに行います。
- 読み取り(無害です)や
DELETE /comments/32(ID 自体がキーなので、再試行すると 404 になります)には不要です。例外は、「最新のものを削除」のような ID で対象を指定しない処理です。 - ストレージの実装方法は
references/patterns.mdを参照してください。
6. 影響範囲、レート制限、キルスイッチ
UI のユーザーは手の動く速さによって制限されます。API を介して公開するものはすべて、コードの速さで、ドキュメントを読んでいない誰かによって、永遠にループで呼び出される可能性があります。
- リリース前に、1 つの呼び出し元がタイトな
while trueループで実行した場合のコストを書き出します。ファンアウト、/indexエンドポイント、一括インポート、リクエスト内でレコードごとの処理を行うものは危険です。 - すべてにレート制限を設け、コストの高い処理にはより厳しい制限を適用します。
X-RateLimit-RemainingとRetry-Afterを返し、適切なクライアントが呼び出しを控えられるようにします。このメタデータがあれば、そうでなければ設定できない厳しい制限を設けられます。- コンシューマーごとのキルスイッチを用意します。想像もしなかった連携機能が原因のインシデントで、必ず必要になります。
7. ページネーション
- 大きくなる可能性のあるコレクションでは、常にカーソルベースにします。
WHERE id > :cursor ORDER BY id LIMIT :nは 100 万件目でも高速なままですが、OFFSETはページを進むほど遅くなり、後から移行するコストも高くなります。 - 上限が常に決まっているコレクション(ユーザーの API キー、プロジェクトの 5 つの環境など)なら、ページ番号やオフセットで問題ありません。
- 上限のないリストは返さないでください。コンシューマーが自分で計算しなくて済むよう、常に
next_page(URL またはカーソル)を含めます。
8. コストの高いフィールドは任意とし、デフォルトでは無効にする
フィールドの取得に追加のサービス呼び出し、大きなテーブルとの結合、または計算が必要なら、デフォルトのレスポンスに含めないでください。
?include=subscriptionやincludes[]配列で取得を制御します。デフォルトのレスポンスは低コストで、一定のコストに保ちます。- GraphQL の考え方の有用な 20%を、コストをかけずに取り入れる方法です。
- ユーザーから求められた場合、またはコードベースがすでに GraphQL の場合を除き、GraphQL を提案しないでください。エンジニア以外には導入のハードルが高く、クライアントが自由にクエリを作成できると、キャッシュが複雑になり、エッジケースが増え、バックエンドも扱いにくくなります。これは最終手段であり、デフォルトではありません。
9. 実装の詳細を漏らさない
見知らぬ人になったつもりでレスポンスを読んでください。正しく利用するために、データの保存方法を知る必要がありますか?
- 漏れる情報の例:クライアントがたどらなければならない
next_comment_idの連鎖、本来はGETにすべき処理でのPOST /fetch_jobとポーリングの組み合わせ、内部の列挙値、内部のテーブル ID、シャード構成によってページサイズが変わるページネーション。 - 単純なインターフェースの背後に隠すか、PR に技術的負債として明記します。公的な契約に、何の説明もなく紛れ込ませてはいけません。
意図的にゲートとしないもの
過剰設計にも設計不足と同じくらい注意してください。
- 最初からバージョニングの仕組みを作り込まないでください。
/v1/プレフィックスは、単なる無料のプレースホルダーではなく、それ自体が公開プロダクト上の選択です。パスまたはヘッダーによるバージョニングは、プロダクトの互換性ポリシーで必要になったときに採用してください。2つ目のバージョンが存在する前に、複数バージョンのネゴシエーションを実装しないでください。 - 呼び出し元が1つで、結果セットに上限がある内部エンドポイントには、
includesやカーソルを追加しないでください。 ページネーションと高コストフィールドのゲートは、応答が大きくなる可能性や、処理コストが高くなる可能性を対象としています。冪等性については、呼び出し元の数によって再試行のリスクがなくなるわけではありません。操作がすでに冪等であるか、重複した効果を明示的に許容できる場合に限り、省略してください。 - 動作している API を、見栄えをよくするために書き直さないでください。 見栄えのために互換性を壊す価値はなく、レビューの時間を費やす価値もありません。
- API の品質は相対的なものだと覚えておいてください。 プロダクトに価値があれば、利用者はひどい API でも統合します(Facebook、Jira)。価値がなければ、美しい API でも救えません。API の品質が決め手になるのは、ほぼ同等のプロダクト同士を比べるときです。本当の欠陥は、API がまったくないことです。ですから、これらのゲートを適用し、必要以上に作り込まないでください。
レビュー出力形式
執筆ではなくレビューを行う場合は、検証を経て確認できた指摘のみを報告し、好みの問題は省いてください。リポジトリのコード、仕様、差分については、file:line 形式で示してください。リポジトリ外の公開済み契約については、固定された URL と正確なセクションを示してください。ソースコードの根拠には、変動するブランチではなく、不変のコミットパーマリンクを使用してください。公開保証がない場合、利用者はその動作を前提にできませんが、バックエンドに未文書化の実装がないことの証明にはなりません。レビュー対象の証拠によってゲートが裏付けられている場合に限り、ゲートに ✓ を付けてください。リポジトリのコンテキストを確認できる場合は、記述がないことを合格とみなさず、差分以外も調べてください。入力が意図的に限定され、追加の証拠を得られない場合は、? (unverified: <reason>) を使用してください。N/A は、ゲートが本当に該当しない場合に限って使用してください。ゲートの要約では、提案された修正を適用した後の仮定上の状態ではなく、レビュー対象の成果物を評価してください。順序は、まず破壊的変更、次にセキュリティ境界、続いてインシデント、最後に使いやすさです。
## API review: <surface>
Scope: public|internal · greenfield|existing
### Breaking changes (blocking)
- <field/endpoint> — <what breaks for a consumer doing X> — file:line
Fix: <additive alternative>
### Security boundary
- <authentication/authorization finding> — <credential or unauthorized action/resource> — file:line
### Incident risk
- <idempotency/blast-radius finding> — <the loop or retry that hurts> — file:line
### Ergonomics
- <boring/pagination/field-cost/implementation-leak finding> — file:line
### Gates: Boring <status> · Compatibility <status> · Authentication <status> · Authorization <status> · Idempotency <status> · Blast radius <status> · Pagination <status> · Expensive fields <status> · No implementation leakage <status>
該当する指摘がなければ、その旨を明確に伝えてください。指摘のないレビューも有効な結果です。
参考資料
references/breaking-changes.md— 互換性マトリックス、バージョニングの手引き、非推奨化の手順。既存のエンドポイントを変更する前に読んでください。references/patterns.md— 実装レシピ:冪等性キー、カーソルページネーション、レート制限ヘッダー、includes。references/examples.md— 簡潔なローカルの例を3つ収録:既存ルート/仕様の差分、新規提案、確立された HTTP RPC ルート。具体的な基準例が役立つ場合に限り読んでください。