DEV Community

Cover image for REST API命名規則:実践スタイルガイド
Akira
Akira

Posted on Originally published at apidog.com

REST API命名規則:実践スタイルガイド

REST APIの命名規則:一貫性のあるエンドポイントを設計する10のルール

2年以上前のコードベースを開けば、そこに傷跡を見つけるでしょう。/getUser/user_list[REDACTED PATH]IDフィールドがorder_idの隣に存在している、といった具合です。どれも単独では何かを壊しません。しかし、積み重なるとチーム全体の作業を遅らせます。

今すぐApidogを試す

命名は、API設計で最も安価に決められる一方、後から変更するには最も高価な要素です。クライアントが/getOrdersに依存すれば、その名前を何年もサポートすることになります。

この記事では、REST APIの命名に関する具体的なルールを、推奨例と非推奨例とともに紹介します。開発者向けREST APIガイドラインと同じ考え方に基づきつつ、チームで議論になりやすい「物事をどう呼ぶか」に焦点を当てます。

コードレビューだけに頼らず、ツールでルールを強制したい場合は、Apidogで共有スキーマに対してエンドポイントを視覚的に定義できます。

1. コレクションには複数形の名詞を使用する

URLは操作ではなく、リソースを表します。コレクションは複数のリソースの集合なので、複数形の名詞で命名します。

推奨:

GET /v1/products
GET /v1/products/89
GET /v1/orders
Enter fullscreen mode Exit fullscreen mode

非推奨:

GET /v1/getProducts
GET /v1/product
GET /v1/productList
Enter fullscreen mode Exit fullscreen mode

複数形なら、次の2つを自然に表現できます。

  • /products:製品のコレクション
  • /products/89:コレクション内の製品89

単数形を使うと、1件のリソースには/product/89、複数のリソースには/productという不自然な構造になりがちです。Microsoft REST APIガイドラインもこの理由から複数形を採用しており、Stripe、GitHub、Shopifyなど多くの公開APIも同じ方式です。

ただし、シングルトンリソースは例外です。ユーザーがカートを1つだけ持つなら、`[REDACTED PATH]数が1のリソースには単数形を使用します。

2. パスから動詞を除外する

HTTPメソッドが動詞の役割を担います。パスにも動詞を含めると情報が重複し、リソースモデルが不明確になります。

推奨:

http
GET /v1/orders/42 (読み取り)
DELETE /v1/orders/42 (削除)
PATCH /v1/orders/42 (更新)

非推奨:

http
GET /v1/fetchOrder/42
POST /v1/deleteOrder/42
POST /v1/updateOrderStatus

動詞ベースのパスは、APIの表面積も増やします。1つのリソースに4つのメソッドがあれば、それぞれを個別にドキュメント化、テスト、キャッシュする必要があります。

キャッシュの無効化も複雑になります。CDNはGET /v1/orders/42をキャッシュし、DELETE /v1/orders/42で無効化できます。どちらも同じURLを指すためです。一方、/fetchOrder/42/deleteOrder/42を同じリソースとして関連付けるのは困難です。

3. URLパスにはケバブケースを使用する

複数の単語で構成されるパスセグメントには、ハイフンを使います。

推奨:

http
/v1/gift-cards
/v1/shipping-addresses

非推奨:

http
/v1/giftCards
/v1/gift_cards
/v1/GiftCards

ケバブケースには、主に3つの利点があります。

  1. Googleはハイフンを単語の区切りとして扱うため、公開APIドキュメントの検索性を高められる
  2. URLに下線が引かれた場合でも、アンダースコアのように区切りが見えなくならない
  3. キャメルケースによる大文字・小文字の違いに起因するバグを避けられる

多くのサーバーでは/giftCards/giftcardsは異なるURLです。入力ミスによる問題も起こり得ます。Zalando RESTful APIガイドラインでも、ケバブケースはMUSTルールです。

4. JSONの命名規則を一つ選び、文書化する

JSONフィールド名は、キャメルケースでもスネークケースでも構いません。問題なのは、両者を混在させることです。

推奨:どちらか一方に統一する

json
{ "orderId": 42, "createdAt": "2026-08-30T09:15:00Z", "totalAmount": 4999 }

json
{ "order_id": 42, "created_at": "2026-08-30T09:15:00Z", "total_amount": 4999 }

非推奨:

json
{ "orderId": 42, "created_at": "2026-08-30T09:15:00Z", "TotalAmount": 4999 }

キャメルケースはJavaScriptやJavaクライアントにマッピングしやすく、スネークケースは読みやすく、Ruby、Python、SQLのカラム名と対応させやすいという特徴があります。Stripeはスネークケースを全面的に採用しています。

APIの主要な利用者に合わせて一方を選び、スタイルガイドに明記しましょう。エンドポイントごとに異なる命名規則が使われるのは、好みの問題ではなくガバナンスの失敗です。

5. ネストは2レベルまでにする

ネストは所有関係を表します。たとえば、`[REDACTED PATH]

推奨:

GET /v1[REDACTED PATH]
GET /v1/orders/1337/refunds
Enter fullscreen mode Exit fullscreen mode

非推奨:

GET /v1[REDACTED PATH]
Enter fullscreen mode Exit fullscreen mode

3レベル以上の深いネストは、リーフリソースがグローバルに一意なIDを持っていても、クライアントにすべての祖先IDを要求します。

払い戻しがID 7を持つなら、次のどちらかで十分です。

/refunds/7
/orders/1337/refunds/7
Enter fullscreen mode Exit fullscreen mode

URLに3つ以上のIDが含まれていたら、平坦化を検討してください。注文が存在すれば、そのパスにユーザーIDを含める必要はありません。/orders/1337だけで独立したリソースとして扱えます。

6. フィルタリング、ソート、ページネーションはクエリパラメータに入れる

パスはリソースを識別し、クエリパラメータは取得方法を指定します。フィルターをパスに埋め込まないようにします。

推奨:

GET /v1/orders?status=active&sort=-created_at&limit=50&cursor=eyJpZCI6NDJ9
GET /v1/products?category=electronics&min_price=1000
Enter fullscreen mode Exit fullscreen mode

非推奨:

GET /v1/orders/active
GET /v1/orders/sorted-by-date-desc
GET /v1/getOrdersByStatusAndDate
Enter fullscreen mode Exit fullscreen mode

sort=-created_atのように、マイナス記号で降順を表す形式はJSON:API仕様に由来します。order=descのような追加パラメータを不要にできるのが利点です。

/orders/activeのようなパスは一見便利ですが、複数のフィルターを組み合わせるたびに新しいエンドポイントが必要になります。

ページネーションのパラメータも統一してください。

  • limit / cursor
  • page / per_page

どちらかを選び、すべてのコレクションで再利用します。APIページネーションガイドでは、カーソル方式とオフセット方式のトレードオフを詳しく解説しています。

7. パスにメジャーバージョンを記述する

APIバージョニングには、主に次の2つの方式があります。

  • パスセグメント:/v1/products
  • ヘッダー:Accept: application/vnd.myapi.v1+json

ヘッダーによるバージョニングは、バージョン間で同じURLが同じリソースを指し続けるため、より「純粋な」RESTと考えられます。Google API設計ガイドも、両方のアプローチが広く使われていると説明しています。

一方、パスバージョニングには運用上の利点があります。

  • すべてのログでバージョンを確認できる
  • ブラウザから直接テストできる
  • Varyを複雑に扱わずキャッシュできる
  • クライアントがバージョン指定を忘れにくい

バージョンヘッダーの欠落による「curlでは動くが、本番では失敗する」という問題は、デバッグを難しくします。

メジャーバージョンのみをパスに含め、/v1/を使用してください。/v1.2/のようなマイナーバージョンは避け、マイナーな変更は後方互換性のある追加としてリリースします。コンテンツネゴシエーションを含む詳しい比較は、APIバージョン管理戦略を参照してください。

8. リソースIDを不透明に扱う

次のような連番IDは、処理件数を推測させ、IDの列挙を容易にします。

/orders/41
/orders/42
/orders/43
Enter fullscreen mode Exit fullscreen mode

攻撃者がIDを順番に試し、認証の隙間を探す可能性があります。不適切なオブジェクトレベル認証は、OWASP API Security Top 10で第1位に挙げられています。

推奨:

GET /v1/orders/ord_9f8e2a71b3
GET /v1/users/550e8400-e29b-41d4-a716-446655440000
Enter fullscreen mode Exit fullscreen mode

非推奨:列挙が問題になる場合

GET /v1/orders/42
GET /v1/invoices/10883
Enter fullscreen mode Exit fullscreen mode

Stripeのord_9f8e2a71b3のような、接頭辞付きのランダムIDは有効なパターンです。

  • 推測しにくい
  • ログでリソース種別を判別しやすい
  • 外部に安全に公開しやすい

ただし、不透明なIDは認証チェックの代わりにはなりません。認証・認可は必ず実装してください。内部では整数の主キーを使っても問題ありません。このルールは、URLで外部に公開するIDに関するものです。

9. 非CRUDアクションをコントローラーリソースとしてモデル化する

注文のキャンセル、支払いの再試行、メールの再送信など、通常のCRUDでは表現しにくい操作は必ず発生します。

推奨:

POST /v1/orders/42/cancel
POST /v1/payments/pay_88a1/retry
Enter fullscreen mode Exit fullscreen mode

非推奨:

PATCH /v1/orders/42        { "status": "cancelled" }
POST  /v1/cancelOrder      { "orderId": 42 }
Enter fullscreen mode Exit fullscreen mode

これは、動詞を使わないルールに対する限定的な例外です。動詞はパスの末尾に置き、対象リソースの下にスコープします。

PATCHでステータスだけを変更すると、状態マシンがフィールド更新の中に隠れてしまいます。注文のキャンセルによって、払い戻し、在庫の解放、通知の送信が発生するかもしれません。単なるフィールド書き込みに見せると、サーバーはペイロードを比較して意図を推測する必要があります。

/cancelのようなアクションエンドポイントなら、次のことを明確にできます。

  • 操作の意図
  • アクション固有の権限
  • 独立した監査証跡
  • キャンセル理由などの専用入力

10. ヘッダーとクエリパラメータの命名規則を統一する

カスタムヘッダーには、HTTPの慣習に合わせてハイフン区切りのパスカルケースを使用します。

Idempotency-Key
Request-Id
Enter fullscreen mode Exit fullscreen mode

古いX-プレフィックスは使用しないでください。RFC 6648によって2012年に非推奨となっています。

ヘッダー名は通信上では大文字・小文字を区別しませんが、ドキュメントやSDKでは常に同じ表記を使います。

クエリパラメータは、JSONボディの命名規則に合わせます。ボディがスネークケースなら、クエリもスネークケースにします。

?min_price=1000&created_after=2026-01-01
Enter fullscreen mode Exit fullscreen mode

?minPrice=1000のように別の規則を使うと、レスポンスではcreated_at、クエリではcreatedAfterという不統一が生まれます。最初の利用者が間違えれば、その後の利用者も同じ間違いをするでしょう。

ルールセット全体を一目で確認

# ルール 推奨 非推奨
1 コレクションには複数形の名詞を使用する /products, /products/89 /getProducts, /productList
2 パスに動詞を含めない DELETE /orders/42 POST /deleteOrder/42
3 パスセグメントにはケバブケースを使用する /gift-cards /giftCards, /gift_cards
4 JSONの命名規則は一つに統一し、文書化する order_id をどこでも使用 orderIdorder_id を混在させる
5 ネストは最大2レベルまで /orders/1337/refunds /users/42/orders/1337/refunds/7
6 フィルターとページネーションはクエリパラメータに入れる ?status=active&sort=-created_at /orders/active
7 パスにメジャーバージョンを含める /v1/products /v1.2/products, バージョンヘッダー
8 リソースIDは不透明にする /orders/ord_9f8e2a71b3 /orders/42(公開、列挙可能)
9 アクションにはコントローラーパターンを使用する POST /orders/42/cancel PATCH{"status":"cancelled"}
10 ヘッダーとパラメータの命名規則を統一する Idempotency-Key, ?min_price= X-IDEMPOTENCY_KEY, ?minPrice= を混在させる

大規模なコンベンションを適用する

Wikiにスタイルガイドを置くだけでは、APIの一貫性は保てません。一貫したAPIを運用するチームは、コードを書く前に設計し、その段階でコンベンションを適用します。これが実践的なAPIガバナンスの中心です。

Apidogでは、エンドポイントをスキーマファーストのビジュアルデザイナーで定義できます。パス、キャメルケース、パラメータ名が、コントローラーコード内の文字列ではなく、明示的な設計成果物になります。

共有コンポーネントを使えば、PaginationErrorMoneyなどのスキーマを一度定義し、すべてのエンドポイントで再利用できます。新しいサービスごとにper_pagepageSizeとして再発明する必要もありません。

設計はレビュー機能を備えたチームワークスペースで管理できます。そのため、3つのクライアントが統合した後ではなく、名前変更のコストが低い設計段階で/getUserOrdersのような問題を発見できます。

承認済みの仕様は、ドキュメント、モックサーバー、テストを駆動します。結果として、設計で承認された名前が、そのままチーム全体が出荷する名前になります。

Apidogをダウンロードして、次の新しいエンドポイントで無料で試してみてください。既存APIの改修は難しくても、新しいAPIで一貫性を保つことは難しくありません。

よくある質問

RESTのURLは複数形と単数形のどちらにすべきですか?

複数のインスタンスを持つリソース(/products/orders/users)には複数形を使います。複数形なら、コレクション(/orders)と個々のメンバー(/orders/42)の両方を自然に表現できます。

`[REDACTED PATH]を使用します。リソースモデリングの詳しい理由は、REST APIとは何かで基本原理から解説しています。

JSONフィールド名にはcamelCaseとsnake_caseのどちらが優れていますか?

どちらにも利点があります。

  • camelCase:JavaScriptを多用するユーザーに適している
  • snake_case:読みやすく、Python、Ruby、Stripeの公開APIと一致する

重要なのは、どちらか一方を選び、スタイルガイドに記載し、スキーマレビューで強制することです。エンドポイント間で命名規則が混在する方が、どちらを選ぶかより大きな問題になります。

APIバージョンはURLに入れるべきですか、それともヘッダーに入れるべきですか?

強力なハイパーメディア要件がない限り、パス(/v1/orders)を推奨します。パスバージョンは、クライアントが追加の設定をしなくても、ログ、キャッシュ、ブラウザテストに表示されます。

ヘッダーによるバージョニングはURLを安定させられますが、クライアントがヘッダーを忘れるとサイレントに失敗する可能性があります。メジャーバージョンだけを使用し、マイナーな変更は後方互換性のある追加としてリリースしてください。

REST APIパスで動詞が許容されることはありますか?

はい。非CRUDアクション用のコントローラーエンドポイントでは許容されます。

http
POST /orders/42/cancel
POST /payments/pay_88a1/retry

動詞はパスの最後に置き、対象リソースのスコープ内に配置します。メソッドはPOSTを使用します。

それ以外では、HTTPメソッドが動詞を伝え、パスは名詞だけで構成します。

Top comments (0)