What's "Express.js" ?

よく使い方を忘れるので、必要な時にサッと読み返せるように超完結にまとめておきます。

>勉強中の関連記事まとめ
>[自分用の勉強記事をまとめた目次　~擬似知識体系~](https://qiita.com/oekaki-hoho-ron/items/3194f560efc461ec03b0)

#Express.jsとは

#インストール

###インストール場所の用意

```zsh
mkdir test
cd test
npm init
```

###Expressをインストール

```zsh
npm install express
```

###Hello World

```zsh
vi app.js
```

```app.js
const express = require('express')
const app = express()

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(3000, () => console.log('Example app listening on port 3000!'))
```

```zsh
node app.js
```

[http://localhost:3000/](http://localhost:3000/)

###ジェネレーターをインストール

```zsh
npm install express-generator -g
```

エラーが出たらとりあえず`sudo`でやる。このときに`-g`やるのとやらないのでどう違うのか要勉強。

```zsh
sudo npm install express-generator -g
```

```zsh
express --version
 > 4.16.1
```

###Expressアプリのテンプレートを生成

```zsh
express test
```

以下のテンプレートが生成される。

```

.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.pug
    ├── index.pug
    └── layout.pug

7 directories, 9 files
```

#Expressのアプリ生成プログラム

express-generatorを使用すると、アプリケーションの骨格を素早く作成できる。上記のように任意のディレクトリにExpressをインストールして`app.js`を作成して、という手順を一つのコマンドで完了できる。

```zsh
express test
cd test
npm install
DEBUG=test:* npm start
```

もしくは

```zsh
npm start
```

###ヘルプ

```zsh
express -h

```

#ルーティング

ルーティングとは、アプリケーションが特定のエンドポイントに対するクライアント要求に応答する方法として、URI (またはパス)と特定のHTTP要求メソッド(GET、POSTなど)を決定すること。

つまりルーティングとは、クライアント側でアプリを操作したときの動作のパスとメソッドを設定すること。

クライアントからのリクエストが合致したときに行う処理を設定すること。

ルート定義の基本構造はこうなる。

```.js
app.METHOD(PATH, HANDLER)
```

|用語|意味|
|---|---|
|app|expressのインスタンス|
|METHOD|HTTP要求メソッド|
|PATH|サーバー上のパス|
|HANDLER|ルートが一致したときに実行される関数|

例えば、Hello Worldの場合。

```.js
app.get('/', function(req, res){
  res.send('Hello World');
});
```


###app.get();

`/`のパスにアクセスされるたびに呼び出されるコールバック関数（`function`）を定義。

###function(req, res){ }

requestとresponseはコールバック関数の引数。

###res.send('Hello World');

responseでsendを呼び出すことで「Hello World」を返す。

#Expressの仕組み

>参考文献
>[expressは一体何をしとるんじゃ・・・](https://qiita.com/ganariya/items/85e51e718e56e7d128b8)

###ファイル構成

|ファイル名|役割|
|---|---|
|app.js|アプリ全体に共通する設定や処理を記述する|
|node_modules/|Expressのモジュールが格納されたディレクトリ。npmでインストールしたファイルが格納されている。基本的に編集することはない|
|packege.json|プロジェクトの名前やバージョンを定義する設定ファイル|
|bin/|wwwファイルのみが入っている。サーバープロセスの起動の処理を格納するディレクトリ。|
|public/|css、js、imgなどの静的リソースが入っている|
|route/|クライアントの要求に対する処理の実行を振り分ける処理ルーティング処理を格納する、サーバ側のコントローラ。|
|views/|UIを格納するディレクトリ。選択したテンプレートエンジンに対応したフォーマットで記述する。サーバ側で画面を作成するときのテンプレート|
|||

ルーティングと処理（ミドルウェア）をつなげていくことでアプリを作成する。

- メイン処理を記述するapp.jsに、アプリ全体のリクエストに共通するミドルウェアを記述
- routesディレクトリ内のjsファイルには、リクエストごとのミドルウェアを記述する

>参考文献
>[Node.js+Expressのファイル構成まとめ](https://torutsume.net/nodejsexpress/)


#express-generatorで生成したテンプレート

公式チュートリアルはサーバーが動作するための必要最低限のサンプルコードだが、`express-generator`を使って生成したサンプルコードの方がもっと実践的なので、こっちのコードを解読していく。

```zsh
express myapp
cd myapp
npm start
```

[http://localhost:3000/](http://localhost:3000/)に接続すると「Express」と表示される。このときにどのファイルがどのファイルにどうアクセスしているのかということを辿って見る。

```index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;
```

```index.jade
extends layout

block content
  h1= title
  p Welcome to #{title}
```

<img width="187" alt="スクリーンショット 2019-11-06 19.33.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278293/e80cf40e-ed4b-781c-e83a-c9f23f0d205a.png">

編集してみる

```index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'ページタイトル', sub: '概要説明' });  //追記
});

module.exports = router;
```

```index.jade
extends layout

block content
  h1= title
  p Welcome to #{title}
  p このサイトの #{sub}    //追記
```

<img width="235" alt="スクリーンショット 2019-11-06 19.40.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278293/bf953e15-055c-1c18-09af-3c113954527d.png">

つまり、`index.js`の`res.render();`に描画したいプロパティ値を追記すると、`index.jade`の`#{プロパティ名}`の部分にレンダリングされるということ。

>参考文献
>[node初心者がexpress-generatorで吐き出されたapp.jsを読んでみる](https://qiita.com/mito_log/items/735f7079f99ec78ea7e6)

#メモ

```zsh
sudo npm install nodemon -g
```
これで編集を加えてもサーバー再起動するまで反映されなかったのが、ブラウザリロードで反映されるようになる。リアルタイム反映ではない。

#サーバーの立て方

###httpオブジェクトの読み込み

httpの各機能をまとめたもので、ここからサーバーのオブジェクトを生成する。

```js
const http = require('http');
```

###Serverオブジェクトの作成

httpオブジェクトのcreateServerメソッドを呼び出してhttp.Serverオブジェクトを生成。これがNode.jsのサーバーとして必要な設定をして実行する。引数に関数を渡す書き方もある。

```js
const server = http.createServer();
```

###リクエストの処理を設定

http.Serverオブジェクトにはさまざまなイベントが用意されており、その処理を組み込むためのメソッドも用意されている。

onメソッドは指定のイベント処理を組み込むもので、第一引数にイベント名、
第二引数に処理や関数を指定する。

下記のコードはrequestというイベントに対してdoRequestという関数を渡している例。requestイベントとはhttpp.Requestオブジェクトがクライアントからのリクエストを受け取ったときに発生し、つまり「ブラウザからサーバーにアクセスした時のサーバー側の処理」を組み込んでいる。

```js
server.on('request', doRequest);
```

###待ち受け開始

http.Serverオブジェクトの準備が整ったらlistenメソッドを実行することでサーバーが待ち受け状態となり、クライアントからリクエストがあれば受け取って処理するようになる。引数にはポート番号を指定する。第二引数としてホスト名を指定したり、第三引数にバックログを指定したり、第四引数にコールバック関数を指定したりできるが、基本的には第一引数のみでよい。

```js
server.listen(3000);
```

###コンソール出力

listenで待ち受け開始した時点でコンソールにメッセージを出力する。デバッグ用。

```js
console.log('接続成功');
```

###まとめ

httpオブジェクトからcreateServerメソッドを呼び出してサーバ設定し、サーバにリクエストがあった時にする処理を指定し、その後サーバを待ち受け状態にして接続成功メッセージを表示する。

```js
const http = require('http');
const server = http.createServer();
server.on('request', doRequest);
server.listen(3000);
console.log('接続成功');
```

もう少しシンプルにすると見やすいかも。基本的にはhttp.createServerオブジェクトであれこれやっているのが分かる。

```js
const http = require('http');
http.createServer.on('request', doRequest);
http.createServer.listen(3000);
```