はじめに
APIを設計する際、ソート順を指定する order や sort といったパラメータをどこに配置するか迷うことがあります。
「POSTメソッドでボディに入れれば、複雑な条件も送りやすいのでは?」と考える方もいるかもしれませんが、Web APIの標準的な設計(特にRESTfulな設計)では、これらはクエリパラメータに載せるのが一般的です。
1. データの性質による使い分け
まず、リクエストに含まれるデータの役割を整理します。
-
リクエストボディ(データ本体):
「サーバーに新しく保管してほしい、あるいは書き換えてほしい」というリソースの中身そのものです。 -
クエリパラメータ(取得条件):
「今あるデータ(リソース)を、どう切り取って、どう見せるか」という取得のカスタマイズ命令です。
order(並び替え)や page(ページング)は、データそのものを変更するものではなく、あくまで「見せ方」を指定する付帯情報であるため、URLの一部であるクエリパラメータに含めるのが自然です。
2. Webインフラとキャッシュの恩恵
URL = キャッシュのキー
ブラウザ、プロキシサーバー、CDN(Cloudflareなど)、NginxといったWebインフラは、基本的にURLをキーにしてコンテンツをキャッシュします。
GET /api/projects?order=created_at:descGET /api/projects?order=price:asc
このようにURLに条件が含まれていれば、インフラ側で「これらは別々の結果を返すリクエストである」と即座に判断でき、適切にキャッシュを活用できます。
ボディを使うデメリット
もしリクエストボディに条件を含めてしまうと、URLはすべて同じ(/api/projects)になります。URLが同一である以上、インフラ側でのキャッシュ制御は極端に難しくなり、パフォーマンス向上の機会を逃すことになります。
3. REST APIの設計思想と「安全なメソッド」
REST APIにおいて、GETメソッドは「安全(Safe)」かつ「冪等(Idempotent)」であることが期待されます。
- 安全: サーバーの状態を変化させない(読み取るだけ)。
- 冪等: 何度実行しても(データが更新されない限り)同じ結果が得られる。
取得条件をすべてURL(クエリパラメータ)に含めることで、「このURLを叩けば、いつでもこの条件の結果が手に入る」という透明性が確保されます。
注意: GETのリクエストボディについて
HTTP仕様上、GETリクエストにボディを含めることは禁止されていません。しかし、多くのライブラリ(axios, fetch)やWebサーバーの仕様では、GETのボディは無視されたり、エラーの原因になったりすることがあります。実務上の相互運用性を考えると、避けるべき設計です。
4. フロントエンド(SPA)での再現性
ReactやVue.jsなどのSPA開発においても、URLに状態(pageやorder)が載っていることは大きなメリットになります。
- URLの共有: 特定の順序で並んだ検索結果のURLをコピーして他人に共有できます。
- 状態の復元: ページをリロードしても、URLから条件をパースすることで、リロード前と同じ表示状態を簡単に復元できます。
- ブラウザ機能の活用: ブラウザの「戻る」「進む」ボタンで、以前の検索条件の結果に正しく遷移できます。
まとめ
order などの制御情報をクエリパラメータに配置するのは、単なる慣習ではありません。
- データの役割(本体か条件か)を明確にするため
- キャッシュ等のWebインフラを最大限に活用するため
- URLの状態共有や再現性を確保するため
これらは、Webというプラットフォームの特性を活かした、非常に合理的な設計判断と言えます。