REST APIの基礎

# Web APIの定義
HTTPなどの通信技術を利用して、異なるシステム間でメッセージを送受信する仕組みです。
主なプロトコルに「REST」と「SOAP」があります。
今回は「REST」について基礎知識をまとめていきます。

参考：
<a href="https://hb.afl.rakuten.co.jp/hgc/1be65697.57fca439.1be65698.9cc4a2e8/_RTtool10000000?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fbook%2F6385779%2F&amp;link_type=text&amp;ut=eyJwYWdlIjoidG9vbCIsInR5cGUiOiJ0ZXh0Iiwic2l6ZSI6IjQwMHg0MDAiLCJuYW0iOjAsIm5hbXAiOiJyaWdodCIsImNvbSI6MCwiY29tcCI6ImRvd24iLCJwcmljZSI6MSwiYm9yIjoxLCJjb2wiOjEsImJidG4iOjF9" target="_blank" rel="nofollow noopener noreferrer" style="word-wrap:break-word;color:#1d54a7">Webを支える技術 HTTP、URI、HTML、そしてREST （WEB＋DB press plusシリーズ） [ 山本陽平 ]</a>


# REST
* REST(Representational State Transfer)はWebアーキテクチャスタイルの一つ。
* RESTの重要な概念の一つにリソースがある。リソースとは、Web上に存在する名前を持った一意な情報、すなわちURI(Uniform Resource Identifier)のこと。
* HTTPの仕組みを利用して、メッセージの送受信を実現している。

## Web APIの利用例
郵便番号検索のWeb APIを利用してみます。
今回アクセスするサービスは[郵便番号検索API](http://zip.cgis.biz/,郵便番号検索API)です。

郵便番号をURLのパラメータに指定すると、XML形式のデータを取得できます。
皇居の郵便番号を指定してみました。
http://zip.cgis.biz/xml/zip.php?zn=1000001

```xml
<ZIP_result>
 <result name="ZipSearchXML"/>
 <result version="1.01"/>
 <result 
 request_url="http%3A%2F%2Fzip.cgis.biz%2Fxml%2Fzip.php%3Fzn%3D1000001"/>
 <result request_zip_num="1000001"/>
 <result request_zip_version="none"/>
 <result result_code="1"/>
 <result result_zip_num="1000001"/>
 <result result_zip_version="0"/>
 <result result_values_count="1"/>
 <ADDRESS_value>
  <value state_kana="トウキョウト"/>
  <value city_kana="チヨダク"/>
  <value address_kana="チヨダ"/>
  <value company_kana="none"/>
  <value state="東京都"/>
  <value city="千代田区"/>
  <value address="千代田"/>
  <value company="none"/>
 </ADDRESS_value>
</ZIP_result>
```
## HTTPメソッド
クライアントからサーバに送信するリクエストメッセージに含まれます。
以下の8種類（TRACEとCONNECTはほとんど使われていないようです）。


| メソッド | 意味 |
|:-----------|:------------|
| GET       | リソースの取得        |
| POST     | リソースへのデータ追加、その他の処理      |
| PUT       | リソースの更新、リソースの作成        |
| DELETE         | リソースの削除          |
| HEAD       | リソースのヘッダの取得       |
| OPTIONS    | リソースがサポートしているメソッドの取得     |
| TRACE    | 自分宛にリクエストメッセージを返す試験     |
| CONNECT    | プロキシ動作のトンネル接続への変更     |

## ステータスコード
サーバからクライアントに送信するレスポンスメッセージに含まれます。
ステータスコードは3桁の数字であり、先頭の数字によって5つに分類できます。

* 1xx：処理中
　　処理が継続していることを示す。

* 2xx：成功
　　リクエストが成功したことを示す。

* 3xx：リダイレクト
　　他のリソースへのリダイレクトを示す。

*　4xx：クライアントエラー
　　クライアントのリクエストが原因でエラーが発生していることを示す。
　　原因を解消するまで再送信不可。

*　5xx：サーバエラー
　　サーバ側が原因でエラーが発生していることを示す。
　　サーバ側の原因が解消すれば、同一リクエストを送信して正常な結果を取得できる可能性がある。

以下のステータスコードはよく使われるコードです。

| ステータスコード | 状態 | 説明 |
|:-----------|:------------|:------------|
| 200       | OK        | リクエスト成功        |
| 201     | Created      | リソースの作成成功（POSTとPUTのレスポンス）        |
| 301       | Moved Permanently        | リクエストで指定したリソースが新しいURIに移動している。新しいURIはレスポンスのLocationヘッダに絶対URIとして入る。        |
| 303        | See Other          | リクエストに対する処理結果が別URIで取得できることを示す。ブラウザからPOSTでリソースを操作した結果をGETで取得する時に使う。        |
| 400       | Bad Request       | リクエスト構文やパラメータが誤っている。        |
| 401    | Unauthorized     | 認証情報が誤っている。WWW-Authenticateヘッダで、クライアントに対して認証方式を伝える。        |
| 404    | Not Found     | 指定したリソースが見つからない。レスポンスボディに理由が入る。        |
| 500    | Internal Server Error     | サーバ側に何らかの異常が発生していて正しいレスポンスを返却できない。レスポンスボディにその理由が入る。        |
| 50３    | Service Unavailable     | サーバがメンテナンスなどで一時的にアクセスできない。レスポンスボディにその理由が入る。        |


## ステートレス性
「ステート」とは状態を表します。「ステートレス」は「状態がない」、「ステートフル」は「状態を保つ」というように考えることができます。

クライアントとサーバのやりとりにおいて、サーバがクライアントの状態（＝セッション情報）を保持するか否かが決まります。

よくある説明例は、ハンバーガーショップの店員と顧客の注文のやりとりです。
「ステートフル」は、顧客が「チーズバーガー」、「ポテト」、「コーラ」と3回話すと、店員は「ご注文はチーズバーガー、ポテト、コーラですね」と認識してくれます。
「ステートレス」は、顧客が「チーズバーガー」、「ポテト」、「コーラ」と3回話すと、店員は「ご注文はコーラですね」とチーズバーガーとポテトの注文を覚えていません。「チーズバーガー、ポテト、コーラをください」と1回で話さないといけません。

### ステートフルの欠点
クライアントの数が増えるほど、サーバが各クライアントの状態を覚えておくことが難しくなること。
サーバを増やし、割り当てをすれば良さそうですが、クライアントの数が決まっていれば可能であるものの、不特定多数の場合はサーバ間でクライアント情報を同期しておく必要が発生してしまいます。

### ステートレスの利点・欠点
サーバが各クライアントの状態を覚える必要がないこと。
クライアントが自分の状態を覚えておき、サーバへのリクエストに必要な情報を記述します。

ただし、送信するリクエスト量が多くなる点や、リクエストごとにサーバの認証が必要となり、サーバの負荷が高まる点といった欠点があります。