0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GETとPOSTの違い、「取得」と「送信」だけだと思っていた

0
Posted at

最近、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の仕組みに乗るための設計ルールなのだと理解しました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?