HTTPメソッドの使い分け
はじめに
業務でWeb APIを用いてシステムの構築を行っていますが、「GETとPOSTはどう使い分ければいいの?」と後輩から聞かれたらふわふわした回答しかできないレベルなのでこれを機に言語化してきます。
GETメソッド
GETメソッドは、リクエストURLで指定したリソースをサーバーにリクエストします。
- 使用法
GETメソッドではリクエストURLもしくはクエリパラメータを用いてリクエストを行います。
var users = await HttpClient.GetFromJsonAsync<IEnumerable<User>>("api/users/search?arg1=cat&arg2=dog");
POSTメソッド
POSTメソッドは、リクエスト本文をサーバーに送信します。
- 使用法
POSTメソッドではリクエストURL、リクエスト本文を用いてリクエストを行います。
var newUsers = new User
{
Id = 2,
Name = "Test"
}
var users = await HttpClient.PostAsJsonAsync("api/users", newUsers);
PUTメソッド
PUTメソッドは、リクエストURLで指定したサーバー上のリソース作成または置換を行います。
- 使用法
PUTメソッドではPOSTメソッドと同じようにリクエストを行います。
var newUsers = new User
{
Id = 2,
Name = "Test"
}
var users = await HttpClient.PutAsJsonAsync("api/users", newUsers);
DELETEメソッド
DELETEメソッドは、リクエストURLで指定したサーバー上のリソースを削除します。
- 使用法
DELETEメソッドではGETメソッドと同じようにリクエストを行います。
await HttpClient.DeleteFromJsonAsync<User>("api/users/2");
GETメソッドとPOSTメソッドの使い分け
前述の通りGETメソッドとPOSTメソッドの使い方はイメージができます。
ではGETメソッドとPOSTメソッドはどういう使い分けをすればよいのでしょうか。
検索
検索を行いたい場合はPOSTメソッドを推奨します。
GETメソッドがデータの取得なので混同しまいがちですが理由があります。
リクエスト本文が送れない
GETメソッドではリクエスト本文が送れません。POSTメソッドのようにModelを送ることができません。
つまり、検索条件が増えてしまうと以下のようになってしまいます。
var users = await HttpClient.GetFromJsonAsync<IEnumerable<User>>("api/users/search?arg1=cat&arg2=dog&arg3=cat&arg4=dog&arg5=cat&arg6=dog&arg7=cat&arg8=dog");
リクエストURLが閲覧履歴に残る
クエリパラメータを用いて検索を行うとその絞り込み条件が履歴に残ってしまい、個人などの機密情報を特定できるためセキュリティ上良くはありません。
また、リクエストヘッダには「Referer」というものがあります。これには直前のウェブページのアドレスが含まれています。
そのためURLに機密情報を入れてしまうとその情報が現在リクエストしているウェブページに送られてしまう可能性があります。
そのため、検索はGETメソッドではなくPOSTメソッドで行いましょう。
PUTとPOSTの使い分け
PUTメソッドでもリソースの作成を行えるからPOSTもPUTも変わらないと思いますが、実際は使い分けがあります。
POSTメソッドは同じリクエストを複数回送っても結果が異なるのに対して、PUTメソッドは同じリクエストは同じ結果が必ず帰ってきます。これによりリソースが常に変わらないPUTメソッドはキャッシュが可能です。
一般的には新規追加処理はPOSTメソッドで、更新処理はPUTメソッドで行います。子の使い分けは会社やプロジェクトによって異なる可能性があるので注意してください。
参考文献
MDN
RFC Document
Discussion