目次


1. リソース設計とURL

  • URLは名詞、操作はHTTPメソッドで表す:GET /users/123 は良く、/getUser?id=123 は避ける
  • コレクションは複数形:/users、/orders
  • ネストは1〜2階層まで:/users/123/orders は可。それより深い場合は /orders?user_id=123 のようにクエリにする
  • 表記を統一する:URLはkebab-case(/order-items)、JSONのキーはsnake_caseかcamelCaseのどちらかに揃える

2. HTTPメソッドの使い分け

メソッド用途冪等性
GET取得○
POST作成・処理の実行×
PUT全体を置き換える○
PATCH一部を更新する△(実装による)
DELETE削除○
  • GETで副作用を起こさない
  • 決済のようなPOSTには Idempotency-Key ヘッダを受け付け、リトライしても二重に処理されないようにする

3. ステータスコード

  • 200 成功、201 作成(Location ヘッダを付ける)、204 返す本文なし
  • 400 リクエスト不正、401 未認証、403 権限なし、404 存在しない、409 競合、422 バリデーションエラー、429 レート制限
  • 500 サーバー側のエラー。エラーなのに 200 を返し、本文の "success": false で失敗を表すやり方はしない

4. エラーレスポンス

  • 形式を統一する。RFC 9457(Problem Details) に準拠するのがおすすめ
{
  "type": "https://example.com/errors/validation",
  "title": "Validation failed",
  "status": 422,
  "detail": "email is invalid",
  "errors": [{ "field": "email", "code": "invalid_format" }]
}
  • 機械が判別できる code と、人が読む message を分ける
  • スタックトレースや内部情報は返さない

5. ページネーション・フィルタ・ソート

  • 件数が多い場合や更新が頻繁なデータでは、カーソル方式(?cursor=xxx&limit=50)がoffset方式よりも安定し、速い
  • limit には上限を設ける(例:最大100)
  • フィルタは ?status=active、ソートは ?sort=-created_at のように書けるようにする
  • レスポンスに next_cursor や has_more を含める

6. バージョニング

  • URLに入れる方式(/v1/...)が最も分かりやすく、運用しやすい
  • 破壊的変更はメジャーバージョンを上げるときだけ行う。フィールドの追加は後方互換を保てる
  • 廃止予定は Deprecation / Sunset ヘッダで事前に知らせる

7. セキュリティ

  • HTTPSを必須にする
  • 認証には OAuth 2.0 / OIDC、またはAPIキーを使う。トークンは短命にし、リフレッシュできる仕組みにする
  • 認可はリソース単位で必ずチェックする(IDOR対策。/users/124 を他人が見られないようにする)
  • 入力をバリデーションし、レスポンスには必要なフィールドだけを返す(Mass Assignment と過剰なデータ露出の対策)
  • レート制限をかけ、RateLimit-* ヘッダで残りの回数を伝える
  • CORSは必要なオリジンだけを許可する
  • 参考:OWASP API Security Top 10

8. パフォーマンス

  • ETag / If-None-Match や Cache-Control でキャッシュを効かせる
  • N+1を避け、関連データは ?include=author のように必要な分だけ返す
  • gzip/brotliで圧縮する
  • 時間のかかる処理は 202 Accepted を返してジョブ化し、ステータスを確認するエンドポイントかWebhookで結果を通知する

9. データ形式

  • 日時は ISO 8601(UTC):2026-10-29T12:00:00Z
  • 金額は小数ではなく整数(最小単位)か文字列で表し、通貨コードを添える
  • IDは推測されにくいもの(UUIDやULID)を検討する
  • null とキーの省略をどう扱うかを決めておく

10. ドキュメントと運用

  • OpenAPI で仕様を定義する(スキーマファーストかコードファーストかを決める)
  • リクエストIDを発行してレスポンスヘッダ(X-Request-Id)に含め、ログを追えるようにする
  • 構造化ログ・メトリクス・トレーシング(OpenTelemetry)を入れる
  • コントラクトテストで、仕様と実装がずれないようにする

補足:Railsでの例

  • エラー形式は rescue_from で一か所にまとめる
  • シリアライズには jbuilder や alba を使う
  • レート制限には Rails 8 標準の rate_limit か rack-attack を使う
  • OpenAPIは rswag か committee で管理する

0件のページ