【随時更新】HTTPに関して改めてまとめてみた

# 概要

HTTPについて調べたことなどをまとめてみた。
間違いなどあれば、指摘をお願いいたします。

# HTTPについて

HTTPはステートレスという方式に基づいてPOSTなどの通信を行なっている。
最初に、ステートレスとその対義語に当たるステートフルについて説明する。

## ステートレス(stateless)

HTTPはステートレスというものに基づいて運用されている。
ちゃんとした言葉でまとめると以下の通り。


> ステートレスとは、システムが現在の状態を表すデータなどを保持せず、入力の内容によってのみ出力が決定される方式。 同じ入力に対する出力は常に同じになる。(IT用語辞典より)


## ステートフル(stateful)

> システムが現在の状態を表すデータなどを保持しており、その内容を処理に反映させる方式。 同じ入力に対する出力が常に同じとは限らず、内部の状態次第で変わることがある。 例えば、対話型のシステムで直前のやり取りの内容を覚えておき、最終的な処理結果にその内容が反映されるような方式をステートフルであるという。(IT用語辞典より)

## わかりにくいのでハンバーガーショップの店員になってみた

### ステートフルver店員

店員：　いらっしゃいませ。
客: チーズバーガーセットください。
店員：チーズバーガーセットですね。セットメニューのドリンクとサイドメニューはいかがいたしましょう？
客: フライドポテトとコーラをください。
店員：承知致しました。少々お待ちくださいませ。

といった感じになる。

### ステートレスver店員

店員：　いらっしゃいませ。
客: チーズバーガーセットください。
店員：チーズバーガーセットですね。セットメニューのドリンクとサイドメニューはいかがいたしましょう？
客: チーズバーガーセットください。チーズバーガーセットですね。セットメニューのドリンクとサイドメニューはいかがいたしましょう？フライドポテトとコーラをください。
店員：承知致しました。少々お待ちくださいませ。

となる。状態を保持しないので、セットメニューを頼んだことを次の会話では保持されていない。そのため、それより前のやりとりにセットのフライドポテトとコーラの情報を加えて店員に頼む必要が出てくる。

# HTTPメソッド

HTTPメソッドとは、サーバーに対して行いたい操作を指定する手段。先ほどのハンバーガーショップの店員でいうと、何を注文するかを指定するものとなる。アプリケーションを作る分には、GETとPOSTだけ知っていれば、問題は無い。ただし、HTTP通信を正しく扱うには、用途に応じてHTTPメソッドを使い分けることが重要。

| メソッド | 意味合い |
|:--|:--|
| GET | 指定されたURIのリソースを取り出す。送信したものにくっついている場合も多いので、chromeの検証で見てみると良い。 |
| POST | GETとは反対にクライアントがサーバにデータを送信する。Webフォームや電子掲示板への投稿などで使用される。GETの場合と同じく、サーバはクライアントにデータを返すことができる。 |
| PUT | 指定したURIにリソースを保存する。URIが指し示すリソースが存在しない場合は、サーバはそのURIにリソースを作成する。画像のアップロードなどが代表的。相手を指定しなければならないので主に開発者が用いる場合が多い？ |
| DELETE | 指定したURIのリソースを削除する。相手を指定しなければならないので主に開発者が用いる場合が多い？ |
| OPTIONS | サーバを調査する。例えば、サーバがサポートしているHTTPバージョンなどを知ることができる。 |
| HEAD | GETと似ているが、サーバはHTTPヘッダのみ返す。クライアントはWebページを取得せずともそのWebページが存在するかどうかを知ることができる。例えばWebページのリンク先が生きているか、データを全て取得することなく検証することができる。 |
| TRACE | サーバまでのネットワーク経路をチェックする。サーバは受け取ったメッセージのそれ自体をレスポンスのデータにコピーして応答する。WindowsのTracertやUNIXのTracerouteとよく似た動作。 |
| CONNECT | TCPトンネルを接続する。暗号化したメッセージをプロキシサーバを経由して転送する際に用いる。 |

### なぜHTTPメソッドの指定でDELETEをみることが少ないのか

DELETEを使う場合にはこのファイルを削除して！などといった指示をする必要がある。しかもそれをURIに基づいて行う。しかしながらセキュリティなどの関係上、URIを公開していることはないといってよい。つまりDELETEを使うのが難しい。そのため、POSTに削除して！という内容を含めて送信することが多い。

### 完全に余談

ブラウザごとに送信できる文字数は制限されている。そのため、何文字なのかも考えてバリデーションを行うといった指定ができると良い。

# HTTPステータスコード 

| Code | Name | 意味合い |
|:--|:--|:--|
| 200 | OK | リクエストが適正であることを指す。リクエストは成功し、レスポンスとともに要求に応じた情報が返される。 ブラウザでページが正しく表示された場合は、ほとんどがこのステータスコードを返している。 |
| 301 | Moved Permanently | 恒久的に移動したことを意味する。リクエストしたリソースが恒久的に移動されているときに返される。Location:ヘッダに移動先のURLが示されている。 例としては、ファイルではなくディレクトリに対応するURLの末尾に/を書かずにアクセスした場合に返される。具体例として、http://www.w3.org/TR |
| 302 | Found | 発見したことを指す。リクエストしたリソースが一時的に移動されているときに返される。Location:ヘッダに移動先のURLが示されている。 元々はMoved Temporarily（一時的に移動した）で、本来はリクエストしたリソースが一時的にそのURLに存在せず、別のURLにある場合に使用するステータスコードであった。しかし、例えば掲示板やWikiなどで投稿後にブラウザを他のURLに転送したいときにもこのコードが使用されるようになったため、302はFoundになり、新たに303,307が作成された。 |
| 400 | Bad Request | リクエストが不正であることを指す。定義されていないメソッドを使うなど、クライアントのリクエストがおかしい場合に返される。 |
| 403 | Forbidden | アクセスなどが禁止されていることを指す。リソースにアクセスすることを拒否された。リクエストはしたが処理できないという意味。 アクセス権がない場合や、ホストがアクセス禁止処分を受けた場合などに返される。 例: 社内（イントラネット）からのみアクセスできるページに社外からアクセスしようとした。 |
| 404 | Not Found | 未検出。リソースが見つからなかった。単に、アクセス権がない場合などにも使用される。|
| 500 | Internal Server Error | サーバ内部エラー。サーバ内部にエラーが発生した場合に返される。 例として、CGIとして動作させているプログラムに文法エラーがあったり、設定に誤りがあった場合などに返される。 |

HTTPステータスコード - Wikipedia

ステータスコードは大まかに分けて5つに分けられる

- 100番台 : 処理中
- 200番台 : 成功
- 300番台 : リダイレクト
- 400番台 : クライアントエラー
- 500番台 : サーバエラー

Webサーバの場合はブラウザに対して、APIサーバの場合はプログラムに対して、それぞれなるべく適切なコードを返すこと
テーブルマナーのようなもので、200と500ぐらいしか使わなくてもサービスを作ることは可能
ただし、ステータスコードは200（OK）なのにレスポンスの中身はError: Not found...のようになると、ユーザは どちらを信じていいかわからなくなる。(通信は成功しているが、プログラムにおいて問題があるといったケースで起こることが多いはず・・・)

## どんなケースで使うのか
### WEBアプリケーション開発

Application Programming Interface(API)の開発で聞くことが多い。
ユーザのデータの要求(リクエスト)に対し、レスポンスを返すときに何事もなければ、RFCに従って上記のステータスコードを返すように設計を行う。ただし、設計するときの考え方によって同じような種類のリクエストに対しても違うレスポンスを返すこともある。

# HTTPにおいて送信するデータの構成

リクエストヘッダとリクエストボディというもので構成されている。

# HTTPにおいて送信するデータの内容

HTTP送受信しているデータの内容を見てみたい場合は、Chromeの検証からNetWorkのTabを選択し、その状態でAmazonなどでログインをしてみると良い。やりとりしている中身をみることが可能。

# HTTPとクライアントサーバモデルの関係性

[Wikipedia クライアントサーバモデル](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%82%B5%E3%83%BC%E3%83%90%E3%83%A2%E3%83%87%E3%83%AB)


# プロトコル

## 概要

コンピュータ等の電子機器間で通信する際の取り決め。どのような状況でどのようなタイプのデータをどのような順番で送るかが記載されている。例えばインターネットでは、[Request for Comments (RFC)](https://ja.wikipedia.org/wiki/Request_for_Comments) という形でプロトコルが提案されている。

インターネットに限らず、機器同士が通信する場合には何らかの手順が必要であり、それらはプロトコルとしてまとめられている場合が多い。複数の手順を階層化する例として、[OSI基本参照モデル](https://ja.wikipedia.org/wiki/OSI%E5%8F%82%E7%85%A7%E3%83%A2%E3%83%87%E3%83%AB)などがある。

[Wikipedia プロトコル(情報工学)](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB#%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6)


# Application Programming Interface(API)について

アプリケーションプログラミングインタフェース（API、英: Application Programming Interface）とは、広義の意味ではソフトウェアコンポーネントが互いにやりとりするのに使用するインタフェースの仕様である。 APIには、サブルーチン、データ構造、オブジェクトクラス、変数などの仕様が含まれる。WEB開発においてはよく「API」と呼ばれているのはこのAPIをさしておらず、「WEB API」をさしていることがほとんど。

[Wikipedia アプリケーションプログラミングインターフェース](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9)

## WEB APIにおいてよく使われるデータのカタチ

### JSON

最近はよっぽどのことがない限りデータの送信内容はこれで統一されているはず。REST APIってやつですな。

# スーパーグローバル変数

この変数と混ぜるな危険。
大事な通信の内容を入れるものであるので、そのままPHPなどで利用してはいけない(セキュリティ的にユーザを盲信してはならない)。そこについてはいつか書く。


# デバッグ(PHP)

開発の際にはvar_dumpだと型まで出るので便利だが、
中身だけ見たいというときにはprint_rのみで十分

しかし、boolean型においてはfalseがprint_rでは何も表示されない。そのため、エラーなどが出ていて調査などをしっかりする場合には基本的にはvar_dumpを利用するのが良い。ただし、print_rには第二引数も存在しているので、しっかり見ていくと良い。