expressフレームワークで作るNode.jsサーバー

# フォーム用のアプリケーションサーバーを用意する必要ができた
というわけで、とりあえずなんか簡単にアプリケーションサーバーになるものはないかと考え、Node.jsで作ってみることにしました。初めてやったので、色々手順やら何やらをおさらいしておきます。

## Node.jsってなんだ
Node.jsはサーバーサイドのJavaScriptの実行環境ということです。言語そのものを指しているわけではなく、実行環境のことをNode.jsと指します。処理するための言語としてJavaScriptを採用されています。

## nodebrewを用意する
macでインストールする場合、homebrewを使ってインストールしてきます。

```
$ brew install nodebrew
```

パスを通します。私はzshを使っているので.zshrcに書いています。

```.zshrc
export PATH=$PATH:/Users/user-name/.nodebrew/current/bin
```

zshを読み込ませたら、バージョンを確認ができると思います。

```
$ nodebrew -v 
nodebrew 1.0.1
```
このようにversionを確認できたらインストール完了です。

## Node.jsをインストール

```
$ nodebrew install stable
```

今回は安定板をインストールしています。因みにNode.jsをインストールすると、合わせてnpmもインストールされます。

```
$ nodebrew list
v11.13.0
v12.9.0

current: none
```

インストールされたnodeをlistでみることができます。

```
nodebrew use stable
```

currentがnoneであったので、useを使ってNode.jsのバージョン管理がこれでできる。

```
nodebrew list
v11.13.0
v12.9.0

current: v12.9.0
```

もう一度listを打ってみると、これでcurrentがstableのNode.jsになっていることが分かります。

## expressをインストール
expressはNode.jsのモジュールを統合したフレームワークです。独自サーバー開発のためのリクエスト処理などを簡単な記述で実現できるようになります。

```
$ mkdir test-server
$ cd test-server
$ npm init
$ npm install express
```

npm initのコマンドは、初期化処理です。この初期化処理を行うことによってpackage.jsonが作成されます。このファイルはjson形式でインストールされたパッケージを管理するために記述されているものです。プロジェクトのNode.jsの初期環境をこれで決められます。npm installでexpressをインストールします。--saveオプションをつけている人も結構いますが、npmバージョン5.0.0以降は不要になったようです。--saveをつけなくても、package.jsonに追加されています。

## サーバーを立てるためのコードを書いてみる

```index.js
/*expressモジュールを読み込んでインスタンス化して、変数へ代入*/
var express = require('express');
var app = express();

/*corsモジュールを読み込む*/
var cors = require('cors' );

/*expressのミドルウェア関数を利用できるようにし、corsモジュールを実行できるようにする*/
app.use(cors());

/*クライアントにアクセスさせたいディレクトリを設定。所謂ひとつのドキュメントルート*/
app.use(express.static('public'));

/*クライアントのgetリクエストがあった時のレスポンス*/
app.get('/', (req, res) => {
  res.send('wlcome to node server!!');
});

/*httpサーバーを運用*/
app.listen(3000, () => {
  console.log('HTTP Server(3000) is running.')
});

/*httpsサーバーを運用*/
var https =  require('https');
var fs = require('fs');
var options = {
  key: fs.readFileSync('cert.ca.key');
  cert: fs.readFileSync('cert/ca.crt');
};

var server = https.createServer(options, app);
server.listen(3001, () =>  {
  console.log(HTTPS Server(3001) is running.');
});
```

## ソースコード上で使われている技術についてのメモ
コメントアウトでは長すぎて説明できないため、別個にこちらで説明します。

### CORSとは？
cors = Cross-Origin Resource Sharing

> ブラウザがオリジン(HTMLを読み込んだサーバのこと)以外のサーバからデータを取得する仕組みで、XMLHttpRequestでクロスドメインアクセスを実現するための仕様です。

ブラウザでAjax通信を行う際には、同一生成元ポリシー(Same Origin Policy)によってWebページを生成したドメイン以外へのHTTPリクエスト（クロスドメイン通信）がブラウザ側の仕様でできません(これをクロスドメイン制約と呼ぶ)。これは、クロスサイトスクリプティングを防止するためですが、Ajax通信で異なるドメインのリソースにアクセスしたいというニーズは常にあるので、CORSはそれを可能にするためのものです。

## httpサーバーとhttpsサーバーを簡単に立てられる
上記の記述だけで簡単なサーバーを立てられます。

```
$ node index.js
HTTP Server(3000) is running.
HTTPS Server(3001) is running.
```

と出てくると思うので、localhostで両方接続してみてください。https接続に関しては、鍵をオレオレ認証で別途作ってください。

## expressの様々なメソッド
### urlencoded

このメソッドは、Content-Typeヘッダーがtypeオプションと一致するリクエストのみを調べるミドルウェアを返します。

```
app.use(express.urlencoded({extended: true}));
```

## ここでいうミドルウェアとは？
ミドルウェアとは、簡単に言うとルーティングで振り分けた先の処理の事です。

#### extended
このオプションを使用すると、URLエンコードされたデータを、クエリ文字列ライブラリ（falseの場合）またはqsライブラリ（trueの場合）で解析することを選択できます。


## Content-Typeとは？
ContentタイプはHTTPヘッダのフィールド名です。MIMEタイプを指定するために使用される。

## じゃ、MIMEタイプって何よ
サーバーから送られてきたデータの種類のことを指す。

以下のようなリクエストヘッダになる

```
Content-Type: text/html; charset=utf-8
```

## jsonメソッド
リクエストをjsonにパースするメソッド

```
app.use(express.json());
```

以上の２つのメソッドを利用することで、リクエストヘッダーのなかにContent-Typeを正しくjosnで表示させることができる。

この上記２つのメソッドを調べていると、記事としてはbody-parserのモジュールを読み込ませて使っているものが多く、v4.16.0以降のexpressを使った表現があまり見られなかった。

## .envから読み込ませる
例えば、ポート番号何番で接続しているかをクライアント側に見られてはいけない。

```
app.listen(process.env.SERVER_LISTEN_PORT);
```

同一階層のパスに.envファイルを作成する。

```.env
SERVER_LISTEN_PORT=3000
```

## 独自ファイルを読み込ませる

```
app.use('/', require('指定したいファイルパス'));
```

## 参考文献

[expressは一体何をしとるんじゃ・・・](https://qiita.com/ganariya/items/85e51e718e56e7d128b8#express%E3%81%AE%E7%94%A8%E8%AA%9E)

[express4.xリファレンス](https://expressjs.com/ja/api.html#express.urlencoded)

[Body-ParserがExpressにexpress.json()として標準搭載されている話
](https://qiita.com/atlansien/items/c587a0bf2f7f9022107c)