- 概要
- 各HTTPメソッドの説明
- GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT, その他
- RESTとは
- RESTの実装例
- 実装例1, 実装例2
HTTP(Hypertext Transfer Protocol)では、クライアントからサーバーにリクエストを送り、そしてレスポンスが返されます。
リクエストには「メソッド」と呼ばれる、リクエストの種類を表す情報として含まれています。
理論上は全部GETメソッドでも通信はできるのですが、実用上の問題から、他のメソッドと使い分けることがほとんどです。
そこで、各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メソッドの代わりに使用します。
先ほど説明したHTTPメソッドについて、上4つについてまとめると次のようになります。
種類 | 冪等性 | 副作用 | 説明 |
---|---|---|---|
GET | あり | なし | リソースを取得 |
POST | なし | あり | リソースを作成 |
PUT | あり | あり | リソースを追加・更新 |
DELETE | あり | あり | リソースを削除 |
ここまで「ファイル」などではなく「リソース」と書いたのは、URIが示す対象が実ファイルとは限らないからです。
例えば「https://www.ipride.co.jp/outline」にGETリクエストを送ると、会社理念のWebページのHTMLが返ってきます。
しかしこれは、サーバー側に「outline」という名前のファイルが存在していることを必ずしも意味しません。
Webサーバーはあくまで、「指定されたURIに対するレスポンスを返している」だけに過ぎないのです。
極端な話、「/outlineにDELETEメソッドを送るとフォームの内容が送信される」といった実装も可能です。
ただ、利用者・開発者の利便性の問題から、各種HTTPメソッドは明瞭なものであるべきです。
そこで、HTTP通信を「リソースに対する操作」であると捉え、それに基づいてメソッドを整理する「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 | ロボットの移動方向を(リクエストボディで)指示する |
- 閲覧数 31685
コメントを追加