オリジナルKdB(科目検索)を作ってみよう -4- Express.jsでWEBアプリことはじめ編

### これまでの記事
- [オリジナルKdB(科目検索)を作ってみよう -1- Node.jsセットアップ編](https://qiita.com/tkkrr/items/2f0d93b6d0c758a88037)
- [オリジナルKdB(科目検索)を作ってみよう -2- パース編](https://qiita.com/tkkrr/items/d8a87b4f598b1b107266)
- [オリジナルKdB(科目検索)を作ってみよう -3- データで遊ぶ編](https://qiita.com/tkkrr/items/8c0f66312212420114a0)

### 前回の要約
- StreamAPIでファイル読み込みした
- 人間が読めるように文字コードを変換した

<img width="1241" alt="スクリーンショット 2019-02-22 16.11.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/3d0c6b57-d3a9-1be1-4166-f9068a2f9771.png">

# この記事を読む前に
この記事はシリーズものです。前回の記事を読んである前提で話を進めるので注意してください。
また、ある特定の人にしかわからない単語が出現する可能性が高いです。あらかじめご了承ください。

### この記事での開発環境
- MacOS 10.14.3
- Visual Studio Code 1.31.1
- Node.js LTS 10.15.1

# 今回やること
- Node.jsの定番WebフレームワークのExpress.jsで遊ぶ
- Hello,World と Routing をする

キーワード **Express.js, Routing, ブラウザ**

# いよいよですよ...
これまではコマンドラインばっかりでしたが、今回からはWebアプリケーションとしての実践を想定した「**ブラウザでの表示**」をやります。今回は**Node.jsといえばコレ！**というくらい定番の[**Express.js**](https://expressjs.com)を使って実装していきます！

<img width="1440" alt="スクリーンショット 2019-02-23 4.19.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/b8f5630e-bf96-7ecb-cf9b-f9e98f71e4cd.png">

> Express.js は、サーバーサイドJavaScriptのNode.jsのWebアプリケーションフレームワークである。シングルページ／マルチページ／混在の各種Webアプリケーションの構築のためにデザインされている。(参考：https://ja.wikipedia.org/wiki/Express.js)

ということで超意訳すると「**Webアプリケーションを作っていく上で色々便利な機能を提供してくれるフレームワーク**」です！「フレームワーク」というのは文字通りで「枠の中のルールに従って記述するだけで豊富な機能を堪能することができる便利なもの」と考えてもらえれば大丈夫です！

Express.jsにおける便利な機能というのは**Routing**や**RESTful API**を容易に作れる機能です。ここら辺の単語はそのうち解説します。

# まずはこれまでのことを忘れよう
Express.jsを理解するためにも、今回はExpress.jsのことはじめだけ書いていきます。
ますはExpress.jsをインストールしましょう。

```shell
$ npm install express
```

インストールが終わったら、これまで作ってきた`index.js`ではなく、新しく`app.js`を作ります。

```javascript:app.js
const express = require('express'); // Express.jsの読み込み
const app = express(); // 新しくサーバーを作る

// ①
app.get( "/", (req, res) => {
    res.send("<h1>Hello world!!</h1>");
});

app.listen(3000); // ポート番号3000でサーバを起動！
console.log("Server started!!");
```

解説はとりあえず置いといて...とりあえずサーバを起動してみましょう
ターミナルを開いて、今回は`app.js`を実行します

```
$ node app.js 
Server started!!

```
ターミナルでコマンドが打てなくなりますが、予定通りに動いている証拠です。安心してください。

では、ChromeやSafariなどのブラウザで次のリンク先を確認してみましょう。
http://localhost:3000/

<img width="1440" alt="スクリーンショット 2019-02-23 4.32.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/6dda0133-bc33-602b-c958-8fd9e973bb20.png">

漠然と`Hello World!!`が表示されていれば成功です！簡単に表示できました！

#### ①-1 Routing
Routingとは、**URLに対応した情報を提供する機能**のことです。例えば今回の場合は、`/`にアクセスしたら`<h1>Hello world!!</h1>`を返すという一連の処理のことをさします。

※`/`しか指定していませんが、直前までの文字列はサーバの環境によって自動的に補完されます。今回の場合は`http://localhost:3000`+`/`ですから、`http://localhost:3000/`にアクセスすれば表示されます。

```javascript
app.get( "/", (req, res) => {
    res.send("<h1>Hello world!!</h1>");
});
```

`app`というサーバを用意して、機能を追加していくというイメージです。`app.get()`は後で説明しますが、第1引数にリンク先の名前、第2引数にアクセスしてきた人へ返す情報を記述します。

- req ... requestの略。ユーザがURLにアクセスした時に渡された情報。
- res ... responseの略。アクセスしてきたユーザに渡す情報。

これはHTTPの処理そのものです。HTTPリクエスト(req)に対して、サーバーからHTTPレスポンス(res)を返す。HTTP一連の流れをこの3行に凝縮したのが今回のHello, Worldです。

HTTPについてより詳しく知りたい方は以下の記事を強くオススメします。

- [HTTPの概要 | MDN - Mozilla](https://developer.mozilla.org/ja/docs/Web/HTTP/Overview)
- [超絶初心者のためのサーバとクライアントの話](https://qiita.com/shuntaro_tamura/items/ae55b99deb9e2a170754)

#### ①-2 RESTful API
**RESTful API**については[こちらの記事](https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2)で詳しく書いてあります。
要約すると「**URI(URL)と機能を紐づけ**」たWebアプリケーションのことです。

例えば、以下のような感じです。

- `http://www.example.com/users/5/edit` ...「IDが5番のユーザ情報を編集する画面」
- `http://www.example.com/users` ... 「登録ユーザの一覧」
- `http://www.example.com/users/4/likes` ... 「IDが4番のユーザがいいねした記事一覧」

これに追加して、HTTPリクエストメソッドというものがあります。**GET, POST, PUT, DELETE, PATCH**など。もう2,3個ありますが、よく使うのはGET,POSTくらいです。

HTTPリクエストメソッドは、リンク先に対してどのような処理をしてほしいかを簡潔に伝える役割を果たします。

- `GET http://www.example.com/users/5/edit`
- `POST http://www.example.com/users/5/edit`

この2つは行われる処理が明確に異なります。前者は「IDが5番のユーザ情報を編集する画面の表示」であり、後者は「入力された情報をもとに、IDが5番のユーザ情報を更新する」という処理になります。

まとめると、**URI(URL)とHTTPリクエストメソッドの原則に基づいて作ること** ＝ **RESTful API** です。それを踏まえて今回のコードをもう一度見てみましょう。

```javascript
app.get( "/", (req, res) => {
    res.send("<h1>Hello world!!</h1>");
});
```

わかりましたか？

ここでは、まだ`/`しか用意していないのでRESTfulとは言い難いですが...。
説明すると、「`/`というURI(URL)に対して`GET`メソッドでHTTPリクエストが飛んできたら、レスポンスとして`<h1>Hello world!!</h1>`を返す処理！」となるわけです。

# もうちっとだけ続くんじゃ
サーバといえば動的に処理してなんぼのもん。ってことで`app.js`に加筆していきます

```javascript
const express = require('express');
const app = express();

app.get( "/", (req, res) => {
    res.send("<h1>Hello world!!</h1>");
});

// 動的処理を追加
app.get( "/:name", (req, res) => {
    res.send("こんにちは！ " + req.params.name + "さん");
});

app.listen(3000);
```

```shell
$ node index.js
# 起動したらブラウザで http://localhost:3000/〇〇 にアクセス
# 〇〇には好きな文字列をいれる。すると...？
```

<img width="242" alt="スクリーンショット 2019-02-23 5.40.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/a329079c-cd7b-ca3f-7179-94c0dd3c0d8c.png">

表示してみるとアドレスに書いた文字列で挨拶します！
先ほどのコードを見ていきます。

```javascript
app.get( "/:name", (req, res) => {
    res.send("こんにちは！ " + req.params.name + "さん");
});
```
Express.jsでは、`:`から始まるURLには**URL自体に情報が入っている**と認識します。その情報をjavascriptで取り扱うには`req.params`の中を参照すればOKです。今回は`/:name`だったので、`req.params.name`に情報が格納されます。

あとは、responseにその情報をそのまま書き込んでしまえば、URLごとに変わる動的ページの出来上がりです！

# Webアプリができそうだぞ！やったね！
これにて、Express.jsを使ったHello,WorldとRoutingは終了です！今回フォームを作る予定はないので`app.post()`を使う予定はありませんが、すぐにできるので色々遊んでみてください！

次回はもう少しオシャレにするためにテンプレートエンジンに触っていきたいと思います！

## 今回のあとがき
Express.jsはNode.jsの中でも特に有名なパッケージです。これをもとに作られたパッケージも非常に多いです。そんなExpress.jsですが、なんとそのモデルとなったのは別言語RubyのWebフレームワーク**Sinatra**。言語を超えても、思想を同じくすることはできる。「お前のソウルが！俺のソウルに受け継がれる！」って感じでしょうか？

それはさておき、もちろんExpress.jsを使わなくても今回と同じ動作を再現することはできます。具体的には`http`というパッケージや`net`というパッケージを使ってヨイショと頑張ればできます。でも...めんどくさいですよ...？ここは有名なフレームワークに乗っかった方が楽だし開発も早くなります。なので、大船に乗った気持ちでフレームワークに頼っていきましょう。

ところで、Express.js以外にはどんなフレームワークがあるのでしょうか？
Node.jsでいえば、Express.jsの開発者が作った[**Koa.js**](https://koajs.com)や[**Hapi.js**](https://hapijs.com)があります。Koa.jsは非同期処理が楽に記述できますし、Hapi.jsならおそらくExpress.jsよりも可読性の高いコードが書けます。

他にも、javascriptに型を与えたTypescriptを使うことで、安全で堅牢な開発を保証してくれる[**Nest.js**](https://nestjs.com)。Ruby on Railsに似たフルスタックな[**Sails.js**](https://sailsjs.com), 新しさが魅力の[**Adonis.js**](https://adonisjs.com)など。Node.jsだけでもこれでもかと多いですが、言語が変われば王道の[**Ruby on Rails**](https://rubyonrails.org)や、大人気Pythonの[**Django**](http://djangoproject.jp), [**Flask**](http://flask.pocoo.org)。フロントエンドのVue.jsと相性がいい[**Laravel**](http://laravel.jp)など。

バックエンド界隈はまさに巨大な生態系を持つ密林です。迷ってしまうこと必至。
考えることは山のようにありますが、まずはなんでもいいからフレームワークに頼って、何か作ってみることが大事なんじゃないかな〜と筆者は思います(特大ブーメラン)。

次の記事 → [オリジナルKdB(科目検索)を作ってみよう -5- Express.jsでWEBアプリ整形編](https://qiita.com/tkkrr/items/9ea97ee9b2823e3a381e)