Node.jsでHTTPメソッドを使う。

##免責事項
この記事は初心者視点でザックリとした説明をしています。正確性に欠ける可能性がございますが、ご了承ください。「明らかに違うよ」ということがありましたら、ご指摘くださると幸いです。

##環境
OS：最新版ではないMacOS
VirtualBox：5.2.26
Vagrant：2.2.6
Ubuntu：ubuntu/bionic64 v20181129.0.0


##目次
1. HTTPメソッドとは
2. HTTPメソッドを使ってみる


#1. HTTPメソッドとは
HTTPメソッド（HTTPリクエストメソッド）とは、WEBブラウザが、HTTPというルールの元に、WEBサーバーに様々な種類のお願いを出すことです。
普段、WEBページにアクセスする場合はGETメソッドが使われますが、
HTTPメソッド1.1は8種類あり、以下のようなお願いを出すことができます。

|リクエストメソッド|意味|CRUD|例（Twitterの例）|
|:----:|:---:|:----------:|:---:|
| GET| リソースの取得 |READ| ツイートをみる
| POST | リソースの追加|CREATE|　ツイートをする
| PUT  | リソースの更新/追加|UPDATE/CREATE|リツイートをする
| DELETE| リソースの削除|DELETE|ツイートを消す
| HEAD  |ヘッダ情報の取得|×|×
| CONNECT|プロキシサーバに通信を開始してもらう|×|×
| OPTIONS|サーバのオプションの確認|×|×
| TRACE |リクエストがどんな経路で届いたか確認|×|×

WEBアプリケーションを作る上では、CRUDだけを意識すれば良いらしいです。

#2. HTTPメソッドを使ってみる
今回はHTTPメソッドのGET、POST、DELETEをNode.jsで作ったサーバーに対してリクエストします。
index.jsファイルを作り、以下のように記述してください。

```JS:index.js
'use strict';
const http = require('http');
const server = http.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/plain; charset=utf-8'
  });
```
>これはサーバーを作っています。
サーバーに対してクライアントからリクエストがあったときに、リクエストを表すオブジェクトの引数 req と レスポンスを表すオブジェクトの引数 res を受け取る無名関数が呼び出されます。

>関数が呼び出されたら、res.writeHead(200, ....)が実行されます。
これは200というリクエストの成功を示すステータスコードと共に、レスポンスヘッダを書き込んでいます。

>レスポンスヘッダには、内容の形式（Content-Type）が、通常のテキスト（text/plain）であるという情報と、文字セット（charset）がutf-8であるという情報を書き出しています。
>>余談ですが、HTTPリクエストをしたら、HTTPレスポンスが返ってきます。
HTTPレスポンスは、
1. HTTPステータスライン
2. HTTPレスポンスヘッダ
3. HTTPレスポンスボディ
の3つに分かれており、それぞれには別の情報が書かれています。
今回は、その中のHTTPレスポンスヘッダに情報を書き込んでいます。

続いて、index.jsファイルに以下を追記してください。

```JS:index.js
  switch (req.method) {
    case 'GET':
      res.write('GET ' + req.url);
      break;
    case 'POST':
      res.write('POST ' + req.url);
      let body = '';
      req.on('data', (chunk) => {
        body = chunk;
      }).on('end', () => {
        console.info('[' + now + '] Data posted: ' + body);
      });
      break;
    case 'DELETE':
      res.write('DELETE ' + req.url);
      break;
    default:
      break;
  } 
   res.end();
})
```
>req.methodにはHTTPリクエストメソッドが格納されているので、Switch文を使い、処理を分岐させています。
GETメソッドならば、そのURLをコンテンツとしてレスポンスに返して終わりです。
POSTメソッドの際は、そのURLをコンテンツとしてレスポンスに返し、さらに追加して送られてくるデータがあります。
送られたデータはchunkに格納され、それを変数bodyに入れています。
DELETEメソッドは、そのURLをコンテンツとしてレスポンスに返して終わりです。res.end()は、resのendメソッドを使いレスポンスの書き出しを終了してます。

続いて以下のようにindex.jsに追記します。

```JS:index.js
server.on('error', (e) => {
  console.error('[' + new Date() + '] Server Error', e);
server.on('clientError', (e) => {
  console.error('[' + new Date() + '] Client Error', e);
});
const port = 8000;
server.listen(port, () => {
  console.info('[' + new Date() + '] Listening on ' + port);
});
```
>次にイベントハンドラの設定です。
サーバー側でエラーイベントが発生したら、errorが呼び出されコンソールに表示されます。
クライアント側でエラーイベントが発生したら、clientErrorが呼び出されコンソールに表示されます。

```JS
const port = 8000;
server.listen(port, () => {
  console.info('[' + new Date() + '] Listening on ' + port);
});
```
>はサーバーが8000番ポートでリクエストを待つという処理です。

全体でこのようなファイル構成になります。

```JS:index.js
'use strict';
const http = require('http');
const server = http.createServer((req, res) => {
	const now = new Date();
	console.info('[' + now + '] Requested by ' + req.connection.remoteAddress);
	res.writeHead(200, {
		'Content-Type': 'text/plain; charset=utf-8'
	});

	switch (req.method) {
		case 'GET':
			res.write('GET ' + req.url);
			break;
		case 'POST':
			res.write('POST ' + req.url);
			let body = '';
			req.on('data', (chunk) => {
				body = chunk;
			}).on('end', () => {
				console.info('[' + now + '] Data posted: ' + body);
			});
			break;
		case 'DELETE':
			res.write('DELETE ' + req.url);
			break;
		default:
			break;
	}
	res.end();
})
server.on('error', (e) => {
	console.error('[' + new Date() + '] Server Error', e);
})
server.on('clientError', (e) => {
	console.error('[' + new Date() + '] Client Error', e);
});
const port = 8000;
server.listen(port, () => {
	console.info('[' + new Date() + '] Listening on ' + port);
});
```

####確認を行う。
それでは、GET、POST、DELETEのHTTPリクエストメソッドが適切に送られるかの確認を行います。
コンソールを2つ立ち上げ、片方をサーバー側、もう片方をクライアント側とします。

サーバー側のコンソールで以下のようにサーバーを立ち上げます。

```サーバー:サーバー
$ node index.js
> [Wed Nov 06 2019 15:59:55 GMT+0900 (GMT+09:00)] Listening on 8000
```

#####GETメソッド

```:クライアント
$ curl -X GET http://localhost:8000
> GET /
```
#####POSTメソッド
POSTメソッドは-dオプションをつけて、情報を送ることができます。

```クライアント:クライアント
$ curl -X POST -d 'こんにちは' http://localhost:8000
> POST /
```
以下のように送った内容がサーバー側に表示されます。

```サーバー:サーバー
[Wed Nov 06 2019 16:44:30 GMT+0900 (GMT+09:00)] Data posted: こんにちは
```

#####DELETEメソッド

```クライアント:クライアント
$ curl -X DELETE http://localhost:8000
> DELETE /
```

\> の後で 'リクエストの種類 / ' と表示されたらうまくリクエストが送られた証拠になります。

##参考
「N予備校 プログラミングコース」
https://www.nnn.ed.nico/
「逆引きcurlコマンドのオプション一覧」
https://www.setouchino.cloud/blogs/99#post-x-post-d