backend-api について
PythonおよびNode.jsサービスのHTTP API設計とレビューを支援するスキルです。API契約、認証境界、エラー処理、フレームワーク実装を扱い、手順とセルフチェック項目も備えています。
主な機能
- 01HTTP API契約の設計とレビュー
- 02ページネーション、フィルタリング、エラー形式
- 03FastAPI、Express、NestJSの構成
- 04セッション、OAuth、トークン認証
- 05OpenAPIと互換性の確認
活用シーン
- 01新しいREST APIの計画
- 02既存FastAPIサービスのレビュー
- 03ページネーションとエラー規約の定義
- 04クライアント認証フローの設計
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ iuliandita/ skills --skill backend-apiインストール後、Claude Code で/backend-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/agent-hygiene.mdauth-and-session-patterns.mdgraphql-grpc-patterns.mdhttp-api-patterns.mdoutput-contract.md詳細
バックエンド API:HTTP サービスの設計と実装
成長に伴っても一貫性を保てる HTTP API を設計・レビューします。Python と Node.js のサービスにおける、コントラクト、認証境界、エラーモデル、フレームワーク構成に焦点を当てます。
対象バージョン(2026年10月):
- FastAPI 0.142.2
- Express 5.2.1(2025-12-01公開)
- NestJS 12.1.2(メジャーリリースです。アップグレード前に移行に関する注意事項を確認してください。12.0.2以降では、重大度の高い マイクロサービス と Fastify のミドルウェアバイパス に関するアドバイザリが修正されています)
- OpenAPI Specification 3.2.1(2026-09-10公開)
- HTTP Semantics:RFC 9110(2022年6月)
- HTTP API の Problem Details:RFC 9457(2023年7月)
- OAuth 2.0 Security Best Current Practice:RFC 9700(2025年1月)
セキュリティチェック(2026-10-28):Multer <2.3.0を使用する Express/NestJS のアップロードスタックは、重大度の高いマルチパート形式のサービス拒否攻撃 CVE-2026-82333 の影響を受けます。
Multer を 2.5.0以降にアップグレードしてください(2.5.0では、リクエスト終了後も保留中の非同期 fileFilter による重大度の高い DoS が修正されています。CVE-2026-113872。2.4.0では、アップロードの中断によるディスク枯渇の中程度の脆弱性が修正されています。
CVE-2026-88932)。また、limits.fieldArrayIndexLimit はアプリケーションの要件に合わせて上限を設定してください。最上位のフレームワークのバージョンだけを確認しても、脆弱なミドルウェアを見逃します。
このスキルでは、次の課題に対応します:
- コントラクト設計 - リソース、メソッド、ステータスコード、スキーマ、バージョニング
- API の使いやすさ - ページネーション、フィルタリング、ソート、冪等性、エラー形式
- フレームワーク構成 - FastAPI の依存関係、Express のミドルウェア、NestJS のモジュールとガード
- 認証 - セッション、ベアラートークン、OAuth/OIDC、BFF とトークン仲介
- レビュー - 不安定なコントラクト、DTO の漏出、認証の混乱、HTTP の誤用
- 範囲を限定したプロトコルパターン - すでに対象となっているプロトコルについて、GraphQL のスキーマ/リゾルバー、および gRPC のコントラクト、デッドライン、再試行、ストリーミングの保護策
使用する場面
- 新しい REST または HTTP API を設計するとき
- 既存の FastAPI、Express、NestJS サービスをレビューするとき
- OpenAPI 仕様や生成されたドキュメントを作成・修正するとき
- ステータスコード、エラー形式、ページネーション、フィルタリング、バージョニング戦略を選ぶとき
- ブラウザー、モバイル、マシン間、サードパーティのクライアント向けに認証フローを設計するとき
- 理解しづらくなったルートやコントローラーの構成をリファクタリングするとき
- 後方互換性を保った API の進化を計画するとき
- 書き込みエンドポイントの冪等性と再試行の動作を定義するとき
使用しない場面
- 単独の GraphQL フェデレーションアーキテクチャや、プロトコル全体を対象とする gRPC プラットフォームの管理。まず依頼の範囲を絞ってください。このスキルが扱うのはサービスのコントラクトパターンであり、フレームワークのカタログではありません。
- データベースのスキーマ、インデックス、レプリケーション、クエリのチューニング。databases を使用してください。
- API 境界外の一般的なバグ発見、競合状態の調査、正確性レビュー。code-review を使用してください。
- 認証バイパス、インジェクション、シークレット、OWASP の指摘事項に関するセキュリティ監査。security-audit を使用してください。
- 自動テストの作成やデバッグ。testing を使用してください。
- デプロイ、コンテナー、ゲートウェイ、イングレス、クラスターの設定。docker、kubernetes、または networking を使用してください。
- API 配信の CI/CD パイプライン設計。ci-cd を使用してください。
- MCP 固有の HTTP サーバーやツールハンドラー。mcp を使用してください。
AI セルフチェック
API コード、ルート設計、または OpenAPI の出力を返す前に、次の点を確認してください。
- リソース名は名詞で、URL の形式は安定しています(
/users/{userId}/sessions。/doUserSessionThingではありません) - メソッドのセマンティクスは RFC 9110 に準拠しています。「状態を変更する GET」や、曖昧な万能用途での PATCH はありません
-
401と403の使い分けは適切です。未認証と、認証済みだがアクセス禁止の場合を区別しています - 所有権を隠す動作は意図的かつ一貫しています。範囲外のリソースに対して
404と403のどちらを返すか決めています - エラーレスポンスの形式は一貫しており、RFC 9457 の Problem Details を推奨します
- リクエスト DTO とレスポンス DTO は明示され、ORM モデルやデータベースモデルとは分離されています
- クライアントや SDK でも検証する場合でも、入力検証はサーバー側で行われます
- 大規模なコレクションや変更頻度の高いコレクションでは、カーソルページネーションのほうが安全なデフォルトであるため、オフセットページネーションを安易に使用していません
- 再試行される可能性がある書き込みエンドポイント(
POST /payments、Webhook の受信、注文の作成)では、冪等性の動作を定義しています - OpenAPI ドキュメントは、実際のハンドラーの動作、例、ステータスコード、認証要件と一致しています
- ファーストパーティのブラウザーアプリでは、長期間有効なベアラートークンをブラウザーのストレージにデフォルトで保存していません
- Cookie ベースのブラウザー認証では、Cookie が自動的に安全だと想定せず、Cookie のスコープと CSRF の動作を考慮しています
- OAuth のガイダンスは最新です。認可コードフロー + PKCE を使用し、インプリシットフローとリソースオーナーパスワードクレデンシャルは使用していません
- セキュリティに関わるデフォルト設定は明示されています。Cookie のフラグ、トークンの TTL、スコープの境界、レート制限を曖昧にしていません
- フレームワークのバージョンを確認済み:FastAPI、Express、NestJS、OpenAPI の例は、現在の API と移行に関する注意事項に合致しています
- 契約の互換性を確認済み:明示的にバージョンを上げる場合を除き、レスポンスコード、ページネーション、エラー、認証の動作は既存のクライアントとの互換性を保っています
- ハンドラー本体内のインジェクションは契約上の不備として指摘:ルートハンドラー内にインジェクション(SQL、コマンド、ヘッダー、パストラバーサル)が見つかった場合、契約レイヤーにおける検証境界の欠落として指摘し、そのレイヤーで修正するよう推奨します。このパターンが広範囲に見られる場合は、完全なインジェクション監査のため security-audit に引き継いでください
- 横断的なエージェントの衛生対策を適用済みです。
references/agent-hygiene.mdを参照してください
パフォーマンス
- データストア側でページネーションとフィルタリングを行ってください。ハンドラー内でスライスするためだけに、コレクション全体を読み込んではいけません。
- フレームワーク、プロキシ、クライアントの各レイヤーでタイムアウトとボディサイズの上限を設定してください。
- 内部処理を最適化する前に、変更したエンドポイントの p95/p99 レイテンシとエラー率を測定してください。
ベストプラクティス
- ルートのグループ化や UI の状態だけに頼らず、ハンドラー内で明示的な認証スコープとテナントのチェックを行ってください。
ワークフロー
**構築とレビュー:**既存のサービスをレビューする場合も、同じ手順を進めてください。API の境界を特定し、契約を監査し、認証を追跡してから、ハンドラーコードに直行するのではなく、実装を公開済みの動作と照合してください。
順序が重要です。ハンドラーより先に契約を定義します。コピーして進捗を追跡してください。
- ステップ 1:境界、呼び出し元、安定性の保証、チーム内のスタイルが明確になっている
- ステップ 2:フレームワークのパターンがコードベースに合致している
- ステップ 3:契約(リソース、メソッド、スキーマ、エラー、ページネーション、バージョニング)が定義されている
- ステップ 4:クライアントの種類に基づいて認証モデルが選択されている
- ステップ 5:契約に基づいてフレームワークのインターフェースが実装されている
- ステップ 6:動作とドキュメントが検証されている(失敗した場合はステップ 3 またはステップ 5 に戻る)
ステップ 1:境界を明確にする
フレームワークのパターンを選ぶ前に、API を明確にします。
- 誰が呼び出しますか? ブラウザーアプリ、モバイルアプリ、サードパーティーのインテグレーター、内部サービス、Webhook の送信元
- どのような種類の API ですか? パブリック API、プライベートアプリのバックエンド、内部サービス、管理者向け API
- 新規開発ですか、それともレビューですか? 新しい設計、段階的な変更、移行、バグ修正
- どのような安定性を保証しますか? 内部利用のみ、バージョン管理されたパブリック API、「ベストエフォート」
- 既存の認証モデルは何ですか? セッション Cookie、JWT ベアラー、API キー、OAuth/OIDC、または未導入
- 既存のコーディング規約は何ですか? エラー形式、ページネーションの形式、バージョニング方式、認証の境界、DTO の命名規則
ユーザーが「エンドポイントを追加するだけ」と依頼した場合は、まず周辺のサービスを確認します。API に関する問題の多くは、サービス内のほかの部分とエラー形式、認証ルール、ページネーションの形式、DTO のスタイルが異なるルートを追加することで発生します。
ステップ 2:フレームワークのパターンを選ぶ
コードベースとチームの制約に合ったフレームワークを選びます。流行に合わせてフレームワークを切り替えてはいけません。
| フレームワーク | 最適な用途 | 注意点 |
|---|---|---|
| FastAPI | 型付きのリクエスト/レスポンスモデルと優れた OpenAPI 出力が必要な Python サービス | ORM モデルを直接公開すること、非同期処理の混乱、ルート関数へのビジネスロジックの詰め込み |
| Express | 薄い Node.js サービス、カスタムミドルウェアスタック、既存の成熟したコードベース | 組み込みの構造がないこと、ミドルウェアへのバリデーションの分散、一貫性のないエラー処理 |
| NestJS | モジュール、ガード、パイプ、インターセプター、DI が役立つ大規模な TypeScript サービス | 過剰な抽象化、デコレーターによる複雑な間接化、多層化による単純な処理フローの隠蔽 |
ステップ 3:まずコントラクトを設計する
ハンドラーを記述する前に、API コントラクトを定義します。
既存のサービスを変更する場合、タスクに移行が明示的に含まれていない限り、現在の URL、エラー、ページネーション、認証に関する規約に合わせます。
- リソースの形式と URI を選びます
- メソッドとステータスコードを選びます
- リクエストとレスポンスのスキーマを定義します
- エラーの形式を定義します
- ページネーション、フィルタリング、ソート、バージョニングのルールを決めます
- その後で初めて、フレームワークの実装を接続します
GraphQL または gRPC の境界では、適用できる範囲で REST/HTTP のルールをデフォルトとして維持し、そのうえで references/graphql-grpc-patterns.md を読み、プロトコル固有のコントラクト、互換性、デッドライン、認可、ページネーション、ストリーミングの安全対策を確認します。
次を優先します。
- 名詞ベースのリソース:
/users/{userId}/sessions - 予測可能なリスト用エンドポイント:
GET /orders?cursor=...&limit=...&status=paid - 明示的な書き込みセマンティクス:作成/コマンドには
POST、全置換にはPUT、部分更新にはPATCH、削除にはDELETE POST /orders/{orderId}/cancelのようなコマンド用エンドポイントには、明示的な再試行セマンティクスを設定します- サービス全体で正規のエラーモデルを 1 つ使用します
メソッドのセマンティクス、ページネーション、冪等性、バージョニングのルールについては、references/http-api-patterns.md を読みます。
ステップ 4:JWT の流行ではなく、クライアントを中心に認証を設計する
まず、クライアントの種類を確認します。
| クライアント | デフォルトの選択肢 | 理由 |
|---|---|---|
| ファーストパーティのブラウザーアプリ | セッション Cookie または BFF/トークン仲介バックエンド | ブラウザーにトークンを保持させるのを可能な限り避けられます |
| ネイティブ/モバイルアプリ | OAuth/OIDC 認可コードフロー + PKCE | パブリッククライアント向けの現在の標準的な方法です |
| サードパーティのインテグレーター | OAuth/OIDC、または OAuth が過剰な場合はスコープ付き API キー | 明確な委任と失効の仕組みを提供します |
| 内部のサービス間通信 | プラットフォーム ID または短期間有効なサービス認証情報 | サービス間でユーザー向けの認証フローを避けられます |
認証ルール:
- 明確な理由がない限り、ファーストパーティの Web アプリではデフォルトでセッションを使用します
- クライアントが実際にトークンを保持するクライアントである場合は、ベアラートークンを使用します
- API キーはマシン認証情報として扱い、あらゆる認証に使える近道として扱わないでください
- スコープまたはロールの境界は API 境界で定義し、無関係なハンドラー内に場当たり的に定義しないでください
- ブラウザーアプリがサードパーティの ID プロバイダーと通信する場合は、暗黙的フローのパターンを復活させるのではなく、認可コードフロー + PKCE と現在のブラウザーアプリ向けガイダンスに従ってください
BFF によるトークン仲介(サードパーティ API を呼び出すファーストパーティのブラウザーアプリ):
Browser -> BFF (session cookie) -> BFF attaches Bearer token -> Upstream API
BFF はアクセストークンをサーバー側で保持し、ブラウザーにトークンが渡ることはありません。
セッション、ベアラートークン、OAuth、BFF、リフレッシュトークン、マシン認証については、references/auth-and-session-patterns.md を参照してください。
ステップ 5:フレームワークのコードを実装する
フレームワークに契約を決めさせず、契約をフレームワークのコードに落とし込みます。
FastAPI
- リクエストとレスポンス用の Pydantic モデルを定義します
- 認証、DB/セッションの取得、共有リクエストコンテキストには依存性注入を使用します
- 一貫した RFC 9457 出力のために例外ハンドラーを登録します
- ルートハンドラーは薄く保ち、ビジネスルールはサービスまたはドメインモジュールに移します
Express
- コントローラーロジックの前に入力を検証します
- ミドルウェアで認証とリクエストコンテキストを設定します
- エラー処理の経路は、共通のミドルウェアにまとめます
- コントローラーはトランスポートアダプターとして保ち、システムのあらゆるルールを置く場所にしないでください
NestJS
- トランスポート境界には DTO クラスを使用します
- 検証にはパイプを、認証にはガードを使用します
- 例外フィルターまたはインターセプターを使用して、レスポンスとエラーの動作を標準化します
- モジュール境界には意味を持たせます。曖昧な概念ごとにモジュールを 1 つ作っても、それはアーキテクチャではありません
ステップ 6:動作とドキュメントを検証する
結果を返す前に、次のチェックを実行します。失敗した場合は修正し、契約上の不備ならステップ 3 に、実装上の不備ならステップ 5 に戻ってから、再度チェックします。
- OpenAPI ドキュメントと実際のルートを照合します
- エンドポイントごとの認証要件を確認します
- 成功時だけでなく、すべての非 2xx レスポンスを確認します
- 空、部分取得、カーソル終端の各状態でリストエンドポイントを検証します
- 作成/決済/Webhook の経路で、リトライと重複送信を確認します
- コマンドエンドポイント(
cancel、resend、approve)を繰り返し呼び出した場合の動作を確認し、リトライの扱いを暗黙のままにしないでください - 新しいエンドポイントを隣接するエンドポイントと比較し、命名、DTO の形式、ページネーションパラメーター、エラーの一貫性を確認します
- 追加のテスト作業は testing に、追加のセキュリティレビューは security-audit に依頼します
契約を守るためのガードレール
バージョニング
- バージョンをむやみに増やすより、後方互換性のある変更を優先します
- 破壊的変更が必要な場合に限り、バージョンを更新します
- サービス内では 1 つのバージョニング方式を使用します。パスによるバージョニング(
/v1/...)が、パブリック API において最も分かりやすいデフォルトです - 1 つの API で、パスによるバージョニング、ヘッダーによるバージョニング、場当たり的な
?version=クエリパラメーターを混在させないでください
OpenAPI の記述
プロジェクトのツールチェーンで 3.2 がエンドツーエンドでサポートされていることが確認できない限り、3.1 を対象に記述してください。詳しくは references/http-api-patterns.md の「OpenAPI Version
Choice」を参照してください。
エラーモデル
- 安定した
type、title、status、ドメイン固有の拡張フィールドを含む RFC 9457 の問題詳細を優先します - バリデーション、認証、ビジネスルールでそれぞれ異なるエラー形式を返さないでください
- 生のスタックトレースや ORM の内部情報をクライアントに漏らさないでください
RFC 9457 に基づく最小限の問題詳細レスポンス:
{
"type": "https://api.example.com/errors/insufficient-funds",
"title": "Insufficient funds",
"status": 422,
"detail": "Account balance is $10.00; transfer requires $50.00."
}
ステータスコードの判断基準(最も適切で範囲の狭いコードを選択します):
| シナリオ | コード | 備考 |
|---|---|---|
| JSON の形式が不正、必須フィールドがない、型が違う | 400 | クライアントリクエストの構文が正しくありません |
| 入力形式は正しいが、ドメインルールに違反している(残高不足、無効な状態) | 422 | 意味的なバリデーション |
| 認証情報がない、トークンの有効期限が切れている | 401 | WWW-Authenticate ヘッダーを含めます |
| 認証済みだが、許可されていない | 403 | 認証情報を要求しないでください |
| リソースが存在しない、または存在するが呼び出し元に知られてはならない | 404 | リソースごとにポリシーを1つ選び、一貫して適用します |
| 書き込みが現在の状態と競合している(古い ETag、重複する一意キー) | 409 | 問題詳細で競合の内容を明示します |
| 異なる本文で Idempotency-Key が再利用された | 422 | 409 ではありません。キーの契約に違反しています |
| リクエストが多すぎる | 429 | Retry-After を含めます |
| 未処理のサーバーエラー | 500 | 本文にスタックトレースを決して漏らさないでください |
一貫した problem+json を実現する FastAPI の例外ハンドラー設定:
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_handler(request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=400,
media_type="application/problem+json",
content={
"type": "https://api.example.com/errors/validation",
"title": "Invalid request",
"status": 400,
"errors": [
{"location": [part for part in error.get("loc", ())
if isinstance(part, (str, int))],
"message": "Invalid value"}
for error in exc.errors()
],
},
)
ページネーションとフィルタリング
- オフセットページネーションは、小規模で変化の少ないバックオフィスのリストに適しています
- ユーザー向け、または書き込み頻度の高いコレクションでは、カーソルページネーションをデフォルトにします
- ソート順は安定しており、文書化されている必要があります
- フィルター名には、内部の SQL 列名ではなく、リソースのフィールド名または明確なドメイン概念を使用します
冪等性とリトライ
- クライアントやゲートウェイが再試行する可能性のある書き込みには、冪等性を定義します
- 決済のような操作やリクエストが再送されやすい操作では、明示的な冪等性キーを使用します
- 非同期ワークフローがある場合は、「リクエストを受け付けた」状態と「副作用が完了した」状態を区別します
Express/NestJS と FastAPI では同じトランザクションプロトコルを使用します。キャッシュの get/write/set の順次処理はアトミックではありません。
- 操作を認証および認可します。ヘッダー長に上限を設け、キーを呼び出し元またはテナントと操作の組み合わせにスコープし、正規化したリクエストをハッシュ化してフィンガープリントを作成します。
- 一意なデータベース制約を使って、スコープ付きキーをアトミックに予約します。既存のレコードがある場合は、フィンガープリントが異なれば拒否し、処理中であることを報告して再実行しないようにします。完了済みの結果は、一致する呼び出し元とフィンガープリントに対してのみ再送します。
- 業務上の変更と完了済みレスポンスのレコードを同じトランザクションでコミットします。外部への副作用には、トランザクショナルアウトボックスとプロバイダーの冪等性機能を使用します。データベースのロールバックでは、すでに送信された決済やメッセージを取り消せません。
- 文書化された再試行期間中、結果を保持します。中断された予約は、定義済みの状態遷移を通じて復旧し、副作用を盲目的に再実行しないでください。同時に発生する重複リクエスト、同じキーを共有する2人の呼び出し元、本文の不一致、副作用の実行後から応答までの間に発生するクラッシュをテストします。
カーソルページネーションのレスポンスエンベロープ:
{
"data": [...],
"next_cursor": "eyJpZCI6MTIzfQ",
"has_more": true
}
カーソルはサーバー側でデコードします(WHERE id > :cursor_id ORDER BY id LIMIT :limit)。カーソルに生の DB オフセットや行番号を決して含めないでください。
不透明なカーソルのエンコード/デコード(FastAPI、クライアントによる改ざんを防ぐ HMAC 署名付き):
import base64, hmac, hashlib, json, os
SECRET = os.environ["CURSOR_SECRET"].encode()
def encode_cursor(payload: dict) -> str:
body = base64.urlsafe_b64encode(json.dumps(payload, separators=(",", ":")).encode()).rstrip(b"=")
sig = base64.urlsafe_b64encode(hmac.new(SECRET, body, hashlib.sha256).digest()[:8]).rstrip(b"=")
return f"{body.decode()}.{sig.decode()}"
def decode_cursor(token: str) -> dict:
body, sig = token.split(".", 1)
expected = base64.urlsafe_b64encode(hmac.new(SECRET, body.encode(), hashlib.sha256).digest()[:8]).rstrip(b"=").decode()
if not hmac.compare_digest(sig, expected):
raise ValueError("invalid cursor")
return json.loads(base64.urlsafe_b64decode(body + "=="))
クライアントは next_cursor を不透明な値として扱います。サーバーが形式を制御し、互換性を損なうことなく変更できます。
グレースフルシャットダウンとローリングデプロイ
ローリングデプロイでは、新しいインスタンスの起動と同時に、古いインスタンスへ SIGTERM が送信されます。API 側で適切に処理しないと、負荷がかかったときに 502 が発生する可能性があります。
- SIGTERM を捕捉し、新しい接続の受け付けを停止して、処理中のリクエストを完了させてから終了します。FastAPI/Uvicorn の場合:
--timeout-graceful-shutdownを設定します(デフォルトでは未設定のため、Uvicorn はタイムアウトなしで処理中のリクエストを待ちます。本番環境では上限のある値を設定してください)。Express 5 の場合:server.close()を呼び出し、ドレイン期間の後にserver.closeAllConnections()を呼び出します。NestJS の場合:app.enableShutdownHooks()とonApplicationShutdownハンドラーを使用します - アプリ側のシャットダウン期間は、オーケストレーターの終了猶予期間(Kubernetes のデフォルトは 30s)より短くします。
app_shutdown < terminationGracePeriodSecondsとしないと、カーネルが処理中の作業を強制終了します - サーバーの HTTP キープアライブタイムアウトは、上流バックエンド接続のアイドルタイムアウト(ロードバランサー、イングレス)より長く設定します。LB がすでに閉じた接続を保持していると、次のリクエストはデッドソケットに到達します。一般的な安全な組み合わせは、アイドルタイムアウト 60s の LB の背後で、サーバーのキープアライブを 65s に設定することです
- ドレインを開始する前に、SIGTERM を受け取ったら失敗状態に切り替わるレディネスプローブを追加します。これにより、処理中のリクエストが完了する間、オーケストレーターは新しいトラフィックのルーティングを停止します
強制してはいけないこと
- 小規模な内部リストやバックオフィステーブルすべてに、カーソルページネーションを強制しないでください
- 新しいフィールドが追加されたというだけで、
/v2を切らないでください - スコープ付き API キーやプラットフォーム ID のほうが適している場合、すべての内部自動化パスで OAuth を必須にしないでください
- 「JWT 認証」がモダンに聞こえるというだけで、ファーストパーティのブラウザーアプリにローカルストレージへのベアラートークン保存を勧めないでください
- シンプルな Express サービスを、不要なレイヤーやデコレーターを備えた擬似エンタープライズアーキテクチャにしないでください
参考ファイル
references/http-api-patterns.md- リソース設計、メソッドのセマンティクス、ステータスコード、バージョニング、ページネーション、フィルタリング、冪等性references/auth-and-session-patterns.md- セッションとベアラートークンの比較、OAuth/OIDC、BFF、リフレッシュトークン、マシンクライアントreferences/graphql-grpc-patterns.md- 範囲を限定した GraphQL と gRPC のコントラクトおよび互換性パターン
出力仕様
完全な仕様については、references/output-contract.md を参照してください。
- スキル名: BACKEND-API
- 成果物の分類:
audits - モード: 条件付き。既存のリポジトリの内容を分析、レビュー、監査、または改善する目的で呼び出された場合は、
references/output-contract.mdのレポートのサイズと証拠に関するルールに従い、成果物をdocs/local/audits/backend-api/<YYYY-MM-DD>-<slug>.mdに書き込みます。質問への回答、概念の説明、新しい成果物の作成、またはコンテンツの生成を目的として呼び出された場合は、仕様に縛られず自由に回答してください。 - 重要度の尺度:
P0 | P1 | P2 | P3 | info(共通仕様を参照。監査・レビューのモードでのみ使用)
関連スキル
- databases - API の背後にあるスキーマ設計、クエリのチューニング、マイグレーション、永続化に関する考慮事項
- code-review - 正確性に関するバグ、ロジックエラー、API 固有ではないレビュー結果
- security-audit - API 設計後の認証バイパス、OWASP に関する指摘、シークレット、セキュリティレビュー
- testing - ルート、統合、コントラクト、エンドツーエンドの検証
- docker - API サービスのコンテナ化
- kubernetes - クラスターへの API サービスのデプロイ
- networking - リバースプロキシ、TLS 終端、CORS に関連するネットワーク境界、ゲートウェイの動作
- ci-cd - API サービスのデリバリーパイプライン
- mcp - MCP 固有の HTTP サーバーと認証パターン
- message-queues - ブローカーを介した非同期配信、
202 Acceptedエンドポイントの背後にあるキュー、ブローカーを介した Webhook のファンアウト
ルール
- ハンドラーを書く前にコントラクトを設計します。 ルートコードを書く前に、リソースモデル、スキーマ、エラー、認証境界を設計します。
- トランスポートに永続化層を漏らしません。 データベーステーブル、ORM エンティティ、内部列挙型はパブリック API のコントラクトではありません。
- フレームワークの構成はシンプルに保ちます。 コントローラーやルートは薄くし、バリデーション、認証、エラー処理を明示的に一元管理します。
- 後方互換性は機能の一つです。 新しいフィールドの追加は容易ですが、クライアントを破壊する変更は大きなコストがかかります。
- 実際の再試行を想定して実装します。 クライアント、プロキシ、ジョブランナーがリクエストを再送することを前提にします。
- プロトコル固有のルールを適用します。 ここでは REST を基本とします。GraphQL と gRPC では、リンク先のリファレンスにあるスキーマ、互換性、デッドライン、ストリーミングに関する独自の確認が必要です。