HTTPメソッドとRESTのおさらい

  •  
 
トビウオ2018年8月13日 - 10:28 に投稿

目次

  • 概要
  • 各HTTPメソッドの説明
    • GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT, その他
  • RESTとは
  • RESTの実装例
    • 実装例1, 実装例2

概要

 HTTP(Hypertext Transfer Protocol)では、クライアントからサーバーにリクエストを送り、そしてレスポンスが返されます。
 リクエストには「メソッド」と呼ばれる、リクエストの種類を表す情報として含まれています。
 理論上は全部GETメソッドでも通信はできるのですが、実用上の問題から、他のメソッドと使い分けることがほとんどです。
 そこで、各HTTPメソッドについて、どういった種類でどういった場合に使用するのかについてまとめました。

各HTTPメソッドの説明

 使用できるHTTPメソッドはHTTPのバージョンによって異なりますが、一般的なHTTP/1.1の場合は8種類あります。
 自分で使用するのはGET・POST・PUT・DELETEがほとんどだと思われます。
 なお、HTTPの仕様で決められているメソッドは8種類ですが、それ以外のメソッドも存在し、IANAで管理されています。
 例えばSpring Bootの場合、CONNECTを除く7種に加えてPATCHメソッドを使用できます。

GET

 最も基本的なメソッドです。サーバーは、指定されたURIのリソースを取り出してクライアントに返却します。
 CRUD(Create-Read-Update-Delete)の思想的には「R」に相当します。
 後述する「REST」においては、冪等性(何度呼び出しても同じ結果を返す)と副作用を起こさない(内部データを改変しない)ことが求められます。

POST

 GETと同じぐらい基本的なメソッドです。クライアントがサーバーにデータを送信するために用います。
 ただ、GETと同様、サーバーがクライアントに何かしらの情報をレスポンスで返しても構いません。
 CRUD(Create-Read-Update-Delete)の思想的には「C」に相当します。
 HTMLの <form>要素はGETとPOSTしか送信できないため、HTTP通信はこの2種がほとんどを占めます。
 後述する「REST」においては、GETと異なり冪等性は求められません。

PUT

 指定したURIにリソースを保存するメソッドです。
 URIが指し示すリソースが存在しない場合、サーバーはそのURIにリソースを作成します。
 CRUD(Create-Read-Update-Delete)の思想的には「C」「U」に相当します。
 後述する「REST」においては、GETと同様に冪等性が求められます。

DELETE

 指定したURIのリソースを削除するメソッドです。
 URIが指し示すリソースが存在しない場合でもエラーにならず、「既に削除されている」ことを返すのが理想的です。
 CRUD(Create-Read-Update-Delete)の思想的には「D」に相当します。
 後述する「REST」においては、GETと同様に冪等性が求められます。

HEAD

 HTTPヘッダーのみを返却するという点を除き、GETメソッドと同じように使用できます。
 その性質から、URIが指し示すリソースが存在するか・更新されているかのチェックに使われます。

OPTIONS

 指定したURIがどういったHTTPメソッドを許容しているかを調べることができます。
 ただ、「(攻撃者含む)第三者に対して無駄に情報を与えると危険」といった思想から、サーバーの設定で無効化することもあります。

TRACE

 サーバは受け取ったリクエストをオウム返しのようにレスポンスとして返します。
 こちらもOPTIONSと同様、セキュリティの観点から無効化されることが多いです。

CONNECT

 TCPトンネルを接続します。暗号化したメッセージをプロキシサーバを経由して転送する際に用います。
 例えば、HTTPS通信でプロキシサーバーがGETメソッドの代わりに使用します。

RESTとは

 先ほど説明したHTTPメソッドについて、上4つについてまとめると次のようになります。

種類 冪等性 副作用 説明
GET あり なし リソースを取得
POST なし あり リソースを作成
PUT あり あり リソースを追加・更新
DELETE あり あり リソースを削除

 ここまで「ファイル」などではなく「リソース」と書いたのは、URIが示す対象が実ファイルとは限らないからです。
 例えば「https://www.ipride.co.jp/outline」にGETリクエストを送ると、会社理念のWebページのHTMLが返ってきます。
 しかしこれは、サーバー側に「outline」という名前のファイルが存在していることを必ずしも意味しません。
 Webサーバーはあくまで、「指定されたURIに対するレスポンスを返している」だけに過ぎないのです。
 極端な話、「/outlineにDELETEメソッドを送るとフォームの内容が送信される」といった実装も可能です。

 ただ、利用者・開発者の利便性の問題から、各種HTTPメソッドは明瞭なものであるべきです。
 そこで、HTTP通信を「リソースに対する操作」であると捉え、それに基づいてメソッドを整理する「REST」思想が生まれました。

RESTの実装例

実装例1

 本のデータベースがあり、それにHTTP通信でアクセスする場合を考えます。
 ユーザーは本の一覧および本の詳細情報を知ることができ、また情報の追加・更新・削除操作を行えるものとします。
 これを単純に考えますと、次のようなAPIを実装すればいいと思われます。

エンドポイント メソッド 意味
/get_book_list GET 本の一覧を返す
/get_book_{ID} GET 指定されたIDの本についての情報を返す
/add_book POST 本の情報を追加する
/replace_book_{ID} POST 指定したIDの本についての情報を更新する
/delete_book_{ID} POST 指定したIDの本についての情報を削除する

 一方RESTでは、次のようなルールでAPIのフォーマットを制限します。

  • APIのエンドポイント名に動詞を使用しない
  • リソースに対する動詞的な操作(参照・追加・変更・削除)はHTTPメソッドで指定する
  • 仕様変更に強くするため、名詞部分も複数形にすることが多い
    • 例えば、同時に複数冊を追加することも可能なようにする
  • 各APIに対するレスポンスでは、HTTPステータスコードを上手く利用する
  • 通信で送受信するデータに、XMLやJSONなど、汎用的なフォーマットを使用する
  • 通信にステート(状態)を持たせず、1通信だけで情報が完結するようにする

 すると、上記のAPIが次のように整理されます。

エンドポイント メソッド 意味
/books GET 本の一覧を返す
/books/{ID} GET 指定されたIDの本についての情報を返す
/books POST 本の情報を追加する
/books/{ID} PUT 指定したIDの本についての情報を更新する
/books/{ID} DELETE 指定したIDの本についての情報を削除する

 この場合、「/books」は「本の一覧」、「/books/{ID}」は「指定したIDの本」を表すリソースとなります。
 それに対してGET〜DELETEメソッドを送ることにより、「本の情報を読み込む」「本を削除する」などを直感的に表現できるのです。

実装例2

 遠隔操縦できるロボットがあり、それをHTTP通信で操作する場合を考えます。
 ロボットは現在位置を情報として持ち、また前後左右に指定した長さだけ進むことができます。
 RESTは「リソースに対して取得・追加・変更・削除」のみを行う思想ですので、こうした複雑な処理だと工夫が必要になります。
 例えば、ロボットの現在位置をリソースと捉え、それに変更操作を行うようにします。

エンドポイント メソッド 意味
/position GET ロボットの現在位置を返す
/position PUT ロボットの新しい位置を伝える(前後左右に動かして到達できない場合はエラーを返す)

 しかし、これだと直感的ではありませんので、あえてRESTにこだわらない選択肢もあるでしょう。
(例えば「/search」エンドポイントは結構な数のWebサイトに存在します)

エンドポイント メソッド 意味
/position GET ロボットの現在位置を返す
/move POST ロボットの移動方向を(リクエストボディで)指示する

コメントを追加

プレーンテキスト

  • HTMLタグは利用できません。
  • 行と段落は自動的に折り返されます。
  • ウェブページのアドレスとメールアドレスは自動的にリンクに変換されます。
CAPTCHA
この質問はあなたが人間の訪問者であるかどうかをテストし、自動化されたスパム送信を防ぐためのものです。