コンテンツにスキップ

REST API: パスパラメータ vs クエリパラメータの違い

問題

GET /products/99
GET /products?id=99

同じ結果を返せるが、意味が違う。違いを説明せよ。

解説

パスパラメータ GET /products/99

「99というIDを持つリソースそのものを指している」 という意味。

  • URIがリソースを一意に識別する(URLがリソースのアドレスになる)
  • RESTの原則に沿った表現
  • キャッシュ効率が高い(CDNやHTTPキャッシュがパスをキーにしやすい)
  • HTTPの冪等性が明確(GETは何度叩いても同じ結果)
GET /products/99       → 商品99番を取得
DELETE /products/99    → 商品99番を削除
PUT /products/99       → 商品99番を更新

パスパラメータなら同じ99というリソースに対してHTTPメソッドを変えるだけで操作を表現できる。

クエリパラメータ GET /products?id=99

「productsの中からid=99の条件でフィルタリングする」 という意味。

  • コレクション(/products)に対する検索・フィルタ
  • 「99というリソース自体」ではなく「99を含む検索結果」
GET /products?category=shoes&color=red&size=26   ← 複数条件フィルタに自然
GET /products?sort=price&order=asc               ← ソート・オプション
GET /products?page=2&limit=20                    ← ページネーション

どちらを使うべきか

用途 推奨
特定リソースを1件取得 パスパラメータ GET /products/99
コレクションをフィルタ クエリパラメータ GET /products?category=shoes
ページネーション クエリパラメータ GET /products?page=2
ソート クエリパラメータ GET /products?sort=price
オプション指定 クエリパラメータ GET /images/logo?width=200

面接での回答ポイント

GET /products?id=99 の問題点は「idというフィールドでフィルタしているように見える」こと。 /products というコレクションURLに対してidで絞り込む形になり、単一リソースへのアクセスとしてセマンティクスが弱い。

また、DELETE /products?id=99 という書き方は直感的でなく、RESTらしくない。