REST APIの設計は、最初に決めたルールがそのまま数年単位で残ります。命名やステータスコードの使い方がエンドポイントごとにバラバラだと、クライアント側の実装者は毎回ドキュメントを読み直すことになり、問い合わせ対応のコストも増えていきます。
この記事では、実務でAPIを設計・運用してきた中で「最初に決めておけばよかった」と感じることの多い4つの観点——リソース命名、HTTPメソッドとステータスコード、エラーレスポンス形式、バージョニング——を整理します。
リソース命名は「名詞・複数形」で統一する
URLは「リソース(名詞)」を表し、操作はHTTPメソッドで表現するのが基本です。/getUsers のような動詞入りのパスが混ざり始めると、命名の判断基準が失われて統一が崩れます。
- コレクションは複数形:
/users、個別リソースは/users/{id} - 階層は所有関係のみ:
/users/{id}/orders(深くても2階層まで) - 単語の区切りはケバブケース:
/order-items - 検索・絞り込みはクエリパラメータ:
/orders?status=pending
「承認する」のようにCRUDに収まらない操作は、POST /orders/{id}/approval のように操作結果をリソースとして表現すると一貫性を保てます。
HTTPメソッドとステータスコードの使い分け
メソッドの選択では冪等性を意識します。GET・PUT・DELETEは何度実行しても結果が同じであるべきで、リトライ設計にも直結します。PUTは全体置換、PATCHは部分更新という区別も守っておくと、クライアント側の誤解を防げます。
ステータスコードは、最低限次の使い分けを揃えておくとクライアント実装が楽になります。
- 200 取得・更新成功 / 201 作成成功 / 204 削除成功(ボディなし)
- 400 リクエスト形式の誤り / 422 形式は正しいが業務ルール違反
- 401 未認証 / 403 認証済みだが権限なし
- 404 リソースなし / 409 競合(重複登録・楽観ロック失敗)
現場でよく揉めるのは「業務エラーを200で返してボディで判定させる」実装です。これをやるとHTTPレイヤの監視やリトライ機構がすべて無効化されるので、避けることを強くおすすめします。
エラーレスポンス形式は全APIで統一する
エラー形式がエンドポイントごとに違うと、クライアントは個別対応を強いられます。RFC 9457(Problem Details)をベースにした構造を全APIで共通化するのが実務的です。
{
"type": "https://example.com/errors/validation",
"title": "Validation Failed",
"status": 422,
"detail": "email の形式が不正です",
"errors": [
{ "field": "email", "message": "メールアドレスの形式で入力してください" }
]
}
ポイントは、機械判定用のコード(type)と人間向けメッセージ(detail)を分けること、バリデーションエラーはフィールド単位の配列で返すことです。スタックトレースや内部実装の情報は絶対に含めません。
バージョニングは「壊す変更」のときだけ上げる
バージョニングの方式はURLパス方式(/v1/users)が最も分かりやすく、ルーティングやログ集計とも相性がよいため、迷ったらこれで問題ありません。ヘッダ方式は柔軟ですが、キャッシュやデバッグの難易度が上がります。
重要なのは方式そのものより「何を破壊的変更とみなすか」の基準です。レスポンスへのフィールド追加は非破壊、フィールドの削除・型変更・意味変更は破壊的としてバージョンを上げる、と決めておきます。クライアント側には「未知のフィールドは無視する」実装を最初から求めておくと、v2を切る頻度を大きく減らせます。
まとめ
REST API設計は「正解を選ぶ」ことより「決めたルールをチーム全体で守り続ける」ことが本質です。リソース命名は名詞・複数形、メソッドは冪等性を意識、エラー形式は共通構造、バージョンは破壊的変更のみ——この4点を設計ガイドラインとして文書化し、レビューのチェック項目に入れるところから始めてみてください。
