最近、Webアプリの基本を学び直す中で、GETとPOSTの違いについて改めて考える機会がありました。
よくある説明としては、
- GETはデータを取得する
- POSTはデータを送信する
というものがあります。
最初はこれを見て、正直こう思いました。
じゃあ、全部POSTでよくない?
実際、POSTだけでも画面表示や検索、登録処理を作ることはできそうです。
ただ、調べていくうちに、GETとPOSTの違いは単なる「取得」と「送信」ではなく、ブラウザやキャッシュ、URL共有、セキュリティなど、Webの仕組み全体に関わるものだと分かりました。
この記事では、自分が「POSTだけでよくない?」と思ったところから、GETとPOSTをなぜ使い分けるのかを整理します。
GETは「見るだけ」の処理
まず整理すると、GETはサーバーから情報を取得するときに使うものです。
例えば、ユーザー一覧を表示する場合です。
GET /users
ユーザー詳細を表示する場合はこうです。
GET /users/1
検索もGETがよく使われます。
GET /search?keyword=java
GETのポイントは、基本的にサーバーの状態を変えないことです。
つまり、
- 一覧を見る
- 詳細を見る
- 検索する
- ページを表示する
といった処理に向いています。
POSTは「何かを送って、状態を変える」処理
POSTは、サーバーにデータを送って、何かを作成したり変更したりするときに使います。
例えば、新しいユーザーを登録する場合です。
POST /users
ログイン処理もPOSTが使われます。
POST /login
問い合わせフォームの送信もPOSTです。
POST /contact
POSTは、
- 登録する
- 送信する
- 保存する
- ログインする
- 購入する
といった処理に向いています。
では、POSTだけでよくないのか?
ここで自分が疑問に思ったのが、「それならPOSTだけでも作れるのでは?」という点でした。
例えば、全部POSTでこう書くこともできます。
POST /getUsers
POST /createUser
POST /deleteUser
アプリケーションとして動かすことは可能だと思います。
ただ、これは動くとしても、Webの仕組みにうまく乗れていない設計になりそうです。
本来はこう書くと、かなり自然です。
GET /users
POST /users
DELETE /users/1
これなら、URLとHTTPメソッドを見るだけで、
- GETなら取得
- POSTなら作成
- DELETEなら削除
と分かります。
ただし、これは単なる「読みやすさ」だけの話ではありません。
GETはキャッシュしやすい
GETは「データを見るだけ」のリクエストなので、ブラウザやCDNがキャッシュしやすいです。
例えば商品一覧ページです。
GET /products
このようなページは、毎回サーバーに問い合わせなくても、キャッシュを使える場合があります。
その結果、
- 表示が速くなる
- サーバー負荷が下がる
- CDNと相性がよい
というメリットがあります。
一方、POSTは「何かを送信して処理する」意味があるため、GETほど自然にはキャッシュされません。
検索や一覧表示まで全部POSTにしてしまうと、Webの仕組みを活かしづらくなります。
GETはURLを共有できる
GETでは、検索条件などがURLに入ります。
GET /search?keyword=java&page=2
この場合、URLをコピーすれば、同じ検索結果を他の人に共有できます。
また、ブックマークもできます。
一方、POSTでは送信内容がリクエストボディに入るため、URLだけでは同じ状態を再現しづらくなります。
そのため、
- 検索結果
- 絞り込み条件
- ページング
- 詳細ページ
などはGETの方が向いています。
更新処理をGETにすると危険
逆に、データを変更する処理をGETにするのは危険です。
例えば、削除処理をGETで作ったとします。
GET /users/1/delete
これはかなり危ないです。
GETは「見に行くだけ」のリクエストとして扱われます。
そのため、ブラウザのプレビュー機能、クローラー、リンク先チェックツールなどが勝手にアクセスする可能性があります。
もしGETアクセスだけで削除が実行されると、
リンクを開いただけでデータが消えた
という事故が起きる可能性があります。
だから、データを変更する処理はPOST、PUT、PATCH、DELETEなどを使うべきです。
POSTはブラウザも「再送信」に注意してくれる
POST送信後にブラウザで更新すると、
フォームを再送信しますか?
のような警告が出ることがあります。
これは、ブラウザがPOSTを「何かを変更するかもしれないリクエスト」として扱っているからです。
例えば、登録フォームを送信した後にページを更新すると、同じ登録処理がもう一度実行される可能性があります。
GETでは基本的にこのような警告は出ません。
つまり、ブラウザ側も、
- GETは何回アクセスしても基本安全
- POSTは再実行すると何かが変わるかもしれない
という前提で動いています。
GETはURLに情報が出る
GETでは、パラメータがURLに表示されます。
GET /login?email=test@example.com&password=abc123
これはよくありません。
URLは、
- ブラウザ履歴
- サーバーログ
- アクセスログ
- Referer
- 分析ツール
などに残る可能性があります。
そのため、パスワードや個人情報のような情報をGETで送るべきではありません。
ログインやパスワード変更、問い合わせフォームなどはPOSTを使います。
POST /login
まとめ
最初は、GETとPOSTの違いは「取得」と「送信」くらいの話だと思っていました。
ただ、調べてみるとそれだけではなく、
- キャッシュできるか
- URLを共有できるか
- ブラウザがどう扱うか
- 意図しないアクセスで事故が起きないか
- URLに残してよい情報か
といった、Webの仕組み全体に関わる違いがありました。
ざっくり使い分けるなら、以下のようになります。
| やりたいこと | HTTPメソッド |
|---|---|
| データを見る | GET |
| 検索する | GET |
| 詳細ページを開く | GET |
| 登録する | POST |
| フォームを送信する | POST |
| ログインする | POST |
| 更新する | PUT / PATCH |
| 削除する | DELETE |
POSTだけでもアプリケーションを作ることはできます。
ただ、GETとPOSTを使い分けることで、ブラウザやHTTPの仕組みに沿った、自然で安全な設計になります。
つまり、GETとPOSTの使い分けは、単なる作法ではなく、Webの仕組みに乗るための設計ルールなのだと理解しました。