Express 入門

公式ドキュメントもかなりシンプルでわかりやすいですが、自分用メモとして。
[Express（日本語ドキュメント）](https://expressjs.com/ja/)

## 最小構成

最低限、これで動かせるよ！というコードです
さくっとWebサーバ立ててなにか試したい時に

### インストール

```bash
$ mkdir myapp
$ cd myapp
$ npm init # entry point: app.js => 任意のファイル名
$ npm install express
```

### ディレクトリ構成

```
(root)
    ├ package.json
    ├ package-lock.json
    ├ app.js
    └ node_modules
```

### コード

```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!'))
```

### 実行

```bash
$ node app.js
# go to http://localhost:3000/
```

http://localhost:3000/ にアクセスすると「Hello World!」と表示されます

## プロジェクトの雛形を作成する

Express プロジェクトの雛形を作成します
テンプレートエンジンの設定や、ディレクトリの作成もしてくれます
本格的にプロジェクトを作成する場合はこちらがおすすめ
[詳しくはこちら](https://expressjs.com/ja/starter/generator.html)

### CLIインストール
雛形作成に必要なパッケージをグローバルにインストールします

```bash
$ npm install express-generator -g
```

### PJ作成

```bash
$ express --view=pug myapp
# --view=pug => 任意のテンプレートエンジン（未指定の場合はjadeになります）
# myapp => 任意のPJ名

$ cd myapp
$ npm install
```

指定できるテンプレートエンジンやその他のオプションは↓で確認できます

```bash
$ express -h
```

### 実行

```bash
$ DEBUG=myapp:* npm start
# go to http://localhost:3000/
```

## ルーティング

### メソッド

`app.METHOD(PATH, HANDLER)` のような形で記述します
Express は、すべてのHTTPリクエストメソッドに対応するメソッドをサポートしています
[メソッドの一覧はこちら](https://expressjs.com/ja/4x/api.html#app.METHOD)

```js
var express = require('express')
var app = express()

app.get('/', function (req, res) {
  res.send('GET request')
})

app.post('/', function (req, res) {
  res.send('POST request')
})
```

また、 `all()` を用いて、全てのメソッドのミドルウェア的なメソッドを定義することも可能です
`next()` でそれぞれのメソッドのハンドラに引き渡します

```js
app.all('/', function (req, res) {
  res.send('Any request')
  next()
})
```

### パス

ルートのパスには正規表現も利用可能です

```js
app.get(/.*fly$/, function (req, res) {
  res.send('/.*fly$/')
})
```

### パラメータ

`:param` の形で記述します
`req.params` で取得できます

```js
app.get('/users/:userId/books/:bookId', function (req, res) {
  res.send(req.params) // => { "userId": "hoge", "bookId": "fuga" }
})
```

### レスポンス

よく使いそうなもの掲載
[一覧はこちら](https://expressjs.com/ja/4x/api.html#res.methods)

```js
// さまざまなタイプのレスポンスを送信します
res.send('GET request')
res.send('<p>some html</p>')
res.send({ some: 'json' })
// etc...

// ビュー・テンプレートをレンダリングします
res.render('index')

// JSON レスポンスを送信します
res.json({ user: 'tobi' })
res.status(500).json({ error: 'message' })
```

### メソッドをまとめて記述する

GET, POST などのメソッドをルートごとにまとめて記述することができます
すっきりしてよき！

```js
app.route('/book')
  .get(function (req, res) {
    res.send('Get a random book')
  })
  .post(function (req, res) {
    res.send('Add a book')
  })
  .put(function (req, res) {
    res.send('Update the book')
  })
```

### ルートハンドラをモジュール化する

ルートごとにファイルを分けて管理できます
大規模なアプリケーション向き

```js:books.js
var express = require('express')
var router = express.Router()

router.get('/', function (req, res) {
  res.send('GET Books')
})

router.get('/:bookId', function (req, res) {
  res.send('GET Some Book')
})

module.exports = router
```

```js:app.js
var books = require('./books')
// ...
app.use('/books', books)
```

```bash
$ curl http://localhost:3000/books # => GET Books
$ curl http://localhost:3000/books/12 # => GET Some Book
```

## 静的ファイル

画像や CSS/JS など、静的ファイルをロードできるようにします
[詳しくはこちら](https://expressjs.com/ja/starter/static-files.html)

```js:app.js
// public ディレクトリに入っているファイルをロードできるようにする
app.use(express.static('public'));

// http://localhost:3000/images/kitten.jpg
// http://localhost:3000/css/style.css
// http://localhost:3000/js/app.js
// http://localhost:3000/hello.html
```