初めてのnode.jsでrestしてみたかった話

# 最初に
JAVAもきな臭いしちょっと飽きてきたのでJAVAでできることをほかの言語でもしてみたいと思ってnode.jsとかPythonとかGoとかいろいろ吟味してnode.jsでやろうと決めて作ってみました。
で、日ごろお世話になってたQiitaに投稿でもしてみようと思ったのもこれができたのがきっかけでした。

## やってみたかったこと
- JAVA以外の言語
- JAX-RSのようなRestful Web サービス
- マルチプロセス

## つかったもの
- Visual Studio Code
- node-v10.13.0-win-x64
- OpenSSL

## 前準備
### サーバ証明書

OpenSSLで適当に作りました。
詳しいことはGoogle先生が教えてくれるはず！

## いざ
### マルチプロセス
[Cluster](https://nodejs.org/dist/latest-v10.x/docs/api/cluster.html)
node.jsの公式を見ました。
core数の半分で動くように作りました。
実働環境だとcore数-2とかがいいのかなーと思いながらコードを組んでましたね。

### HTTPとHTTPS 
[HTTP](https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_http_createserver_options_requestlistener)
[HTTPS](https://nodejs.org/dist/latest-v10.x/docs/api/https.html#https_https_createserver_options_requestlistener)
どっちもnode.jsの公式

```
const service = receipt(entrance);
const server = http.createServer({
	IncomingMessage: incomingMessage,
	ServerResponse: serverResponse
}, service);
server.listen(80);
const https_server = https.createServer({
	IncomingMessage: incomingMessage,
	ServerResponse: serverResponse,
	key: '<keyfile>',
	cert: '<cerfile>'
}, service);
https_server.listen(443);
function receipt(func){
	return async function(){
		const app = await func.apply(this, arguments);
		return app;
	}
}
async function entrance(req, res){
	...しょりいろいろ...
	return new Promise(resolve => {
		resolve(this);
	});
}
```

incomingMessageとserverResponseはそれぞれfunction定義していてその中でヘッダの値をプロパティにしてみたりということができます。
csrfトークンとか使うときに共通部品的に処理できるようになるので便利に使えるんじゃないかなと思ってます。

### RESTful
といえば、GET、POST、PUT、DELETEで実行するのでapiをクラスで定義してそれぞれのメソッドを定義しました。

```
class api1 {
	async get(req, res){
		console.log('api1.get executed.');
		res.writeHead(200, {'Content-Type': 'text/plain'});
		return new Promise(resolve => resolve('hello world. get ' + new Date()));
	}
	async post(req, res){
		res.writeHead(201, {'Content-Type': 'text/plain'});
		return new Promise(resolve => resolve('hello world. post ' + new Date()));
	}
	async put(req, res){
		res.writeHead(200, {'Content-Type': 'text/plain'});
		return new Promise(resolve => resolve('hello world. put ' + new Date()));
	}
	async delete(req, res){
		res.writeHead(204, {'Content-Type': 'text/plain'});
		return new Promise((resolve, reject) => {
			reject({
				status: 403,
				message: 'hello world. delete ' + new Date()
			});
		});
	}
}

```

上述のentranceでちょいちょいしてGETとgetに変換して実行するようにしてます。
これを実行すると。こうなります↓
> hello world. get Fri Nov 16 2018 xx:xx:xx GMT+0900 (GMT+09:00)


### interceptor
JAX-RSといえばinterceptorだと私は思ってます。
これを実行させるにはメソッドが呼び出されるときに実行するようにします。

```
var method = intercepter1(get);
var result = await method(req, res);
```

```
function interceptor1(func) {
	return async function(){
		console.log('execute interceptor1');
		const app = await func.apply(this, arguments);
		console.log('complete interceptor1');
		return app;
	}
}
```

実行したときに↓がデバッグコンソールに表示します。
> execute interceptor1
> api1.get executed.
> complete interceptor1

**ということでここまで**

## 感想
さらっと作ってみたけど簡単で短いコーディングで結構な機能を盛れるってすごいなーって思いながら組んでました。
マルチプロセスはcurlで投げてvscodeで止めてブラウザで投げてってやってみたらちゃんと機能してました。
async/await・Promise地獄見づらさと見やすさが混在してるけどシングルスレッドというのは本当にいいものだと思います。
そして何よりも処理の速さはとても魅力的だと感じました。安定動作が可能なら可用性が非常に高いものなんじゃないでしょうかね。
これを仕事に出来てお金を稼げたらいいなーｗ