Web API: The Good Partsを読んだので「HTTPの仕様」についてまとめた


## はじめに
APIの勉強のために、[Web API: The Good Parts](http://www.amazon.co.jp/Web-API-The-Good-Parts/dp/4873116864)を読みました。平易な日本語で書いてあるので、読みやすかったです。
とはいえ、何度も本を読み返すのは大変なので、自分用まとめも兼ねて書こうと思った次第です。

1個1個まとめていくと結構な量があるので今回は「HTTPの仕様」についてまとめました。主にステータスコードとメディアタイプのまとめです。
本でいうと4章に書いてあります。

## この記事も参考に
Web API: The Good Partsの他のまとめ記事もここに載せておきます。

- 2.2: [Web API: The Good Partsを読んだので「良いURI」についてまとめた](http://qiita.com/soyanchu/items/5ca902a7353bb08b7f12)
- 2.6: [Web API: The Good Partsを読んだので「OAuthの仕組み」についてまとめた](http://qiita.com/soyanchu/items/244ab3a35acf4dbf0030)
- 3章: [Web API: The Good Partsを読んだので「レスポンスデータの設計」についてまとめた](http://qiita.com/soyanchu/items/f940a9c86b3122f99c41)
- 5章: [Web API: The Good Partsを読んだので「設計変更しやすいWeb API」についてまとめた](http://qiita.com/soyanchu/items/34f8e164c24f044e80a3)

記事を書く順番は章ごとではなく結構バラバラです。

## HTTPの仕様を利用する意義

HTTP標準の仕様をできるかぎり利用して作られたAPIは第三者にとっても、独自実装に比べればずっと理解しやすく、バグの混入を減らしたり、APIが広く使われる、あるいは既に存在するライブラリやコードが再利用可能になる可能性がずっと高くなります。
HTTPは[RFC7230](http://www.hcn.zaq.ne.jp/___/WEB/RFC7230-ja.html)に定義されています。

HTTPは一対のリクエストとレスポンスで構成されており、それぞれにはヘッダ(リクエストヘッダとレスポンスヘッダ)とボディ(リクエストボディとレスポンスボディ)があります。

ボディはレスポンスならサーバから返ってくるデータ、リクエストの場合はサーバに送信するデータが入ります。なお、ヘッダはそれぞれに関するメタ情報を入れることが出来ます。

それではHTTPをエンベロープとしてAPIで有効に使うための方法を見ていきます。

## ステータスコード

ステータスコードとは、HTTPのレスポンスヘッダの先頭に必ず入っている3桁の数字で、例えば"200 OK"や"404 Not Found"、"500 Internal Server Error"などです。

ステータスコードのおおよその意味合いは以下のとおり。

| ステータスコード       | 意味                                        |
|----------------|-------------------------------------------------------|
| 100番台       | 情報 |
| 200番台       | 成功                    |
| 300番台       | リダイレクト                     |
| 400番台     | クライアントに起因するエラー           |
| 500番台       | サーバサイドに起因するエラー           |

詳細なステータスコード一覧は以下のとおりです。

| ステータスコード | 名前                     | 説明                                               |
|------------------|--------------------------|----------------------------------------------------|
| 200              | OK                       | リクエストは成功した                               |
| 201              | Created                  | リクエストが成功し、新しいリソースが作られた       |
| 202              | Accepted                 | リクエストは成功した                               |
| 204              | No Content               | コンテンツなし                                     |
| 300              | Multiple Choices         | 複数のリソースが存在する                           |
| 301              | Moved Permanently        | リソースは恒久的に移動した                         |
| 302              | Found                    | リクエストしたリソースは一時的に移動している       |
| 303              | See Other                | 他を参照                                           |
| 304              | Not Modified             | 前回から更新されていない                           |
| 307              | Temporary Redirect       | リクエストしたリソースは一時的に移動している       |
| 400              | Bad Request              | リクエストが正しくない                             |
| 401              | Unauthorized             | 認証が必要                                         |
| 403              | Forbidden                | アクセスが禁止されている                           |
| 404              | Not Found                | 指定したリソースが見つからない                     |
| 405              | Method Not Allowed       | 指定されたメソッドは使うことが出来ない             |
| 406              | Not Acceptable           | Accept関連のヘッダに受理できない内容が含まれている |
| 408              | Request Timeout          | リクエストが時間以内に完了しなかった               |
| 409              | Confilct                 | リソースが矛盾した                                 |
| 410              | Gone                     | 指定したリソースは消滅した                         |
| 413              | Request Entity Too Large | リクエストボディが大きすぎる                       |
| 414              | Request-URI Too Long     | リクエストされたURIが長すぎる                      |
| 415              | Unsupported Media Type   | サポートしていないメディアタイプが指定された       |
| 429              | Too Many Requests        | リクエスト回数が多すぎる                           |
| 500              | Internal Server Error    | サーバ側でエラーが発生した                         |
| 503              | Service Unavailable      | サーバが一時的に停止している                       |

まず大きく分けて200番台が何を表すか、300台が…というのを理解した後に、詳細なものを理解していけばいいと思います。

## キャッシュとHTTPの仕様

キャッシュは、サーバへのアクセスの頻度や通信料を減らすためにクライアント側で一度取った情報を保存しておき、再度必要になった時にあらかじめ取得してあった情報を利用することを言います。

キャッシュのメリットは以下のとおりです。

- サーバへの通信を減らすことが出来るため、ユーザーの体感速度を上げることができる
- ネットワーク接続が切れた状態でもある程度サービスを継続できる
- サーバへの通信回数、転送量を減らすことでユーザーの通信コストを下げることができる
- サーバへのアクセス回数が減ることで、サーバの維持費用を抑えることができる

キャッシュはユーザー体験にもクライアント、サーバ両方のコストにも大きく影響を与えるため、有効に活用するべきです。

## メディアタイプ

HTTPのリクエスト、レスポンスでは送信するデータ本体の形式を表すためにメディアタイプを指定する必要があります。
メディアタイプとは簡単に言うとデータ形式のことです。

application/jsonのような形で指定して、 

```
トップレベルタイプ名/ サブタイプ名[; パラメータ]
```

のようにして記述します。


代表的なメディアタイプは以下のとおり。

| メディアタイプ           | データ形式                                 |
|--------------------------|--------------------------------------------|
| text/plain               | プレーンテキスト                           |
| text/html                | HTML文書                                   |
| application/xml          | XML文書                                    |
| text/css                 | CSS文書                                    |
| application/javascript   | JavaScript                                 |
| application/json         | JSON文書                                   |
| application/rss+xml      | RSSフィード                                |
| application/atom+xml     | Atomフィード                               |
| application/octet-stream | バイナリデータ                             |
| application/zip          | zipファイル                                |
| image/jpeg               | JPEG画像                                   |
| image/png                | PNG画像                                    |
| image/svg+xml            | SVG画像                                    |
| multipart/form-data      | 複数のデータで構成されるWeb Ｆｏｒｍデータ |
| video/mp4                | MP4動画ファイル                            |
| application/vnd.ms-excel | Excelファイル                              |

## おわりに

ステータスコード、メディアタイプはどのようなものか、どのような種類があるのか、というのをはっきりとわかっていなかったのでまとめてみました。
まだざっくりとしかまとめていないので、あとで追記していこうと思います。
参考になれば幸いです。