node.js ✖️ express.js ✖️ mysql のwebアプリheroku公開までの方法

#この記事でできること
node.jsとexpress.js, mysqlを使用したアプリをherokuで公開することができるようになる。
特にnode.jsをherokuでデプロイする時にどうmysqlと接続すれば良いか、かなり詰まったのでこの記事
にまとめる。


#参考記事

基本のデプロイの参考記事
[Vue.jsで作ったアプリをHerokuにデプロイ](https://qiita.com/kottyan/items/dbc1edb82e8562235fac)

herokuでアップロードするファイルでmysqlを使用する場合の参考記事
①[Tutorial: How to Create a MySQL Database with Heroku](https://www.youtube.com/watch?v=aEm0BN493sU)

②[Connecting MySql and NodeJS on a Heroku Server (Github code)
](https://www.youtube.com/watch?v=2OGHdii_42s)


①はherokuでclearDBを使用する方法の基本動画
②は実際にデータベースに入れた値を表示する記述まで記載の動画


##①ローカル開発
<h3>webアプリVSCode記述前の準備</h3>

```
mkdir hellotaro
cd hellotaro
```
githubにてリポジトリを作成(READMEを作っておく）
URLをコピーする

hellotaroの場所にターミナルでいった状態で

```
git init
git clone [githubのリポジトリのURL([]この外側のカッコは不要]]
```

これで github のリポジトリとファイルの紐付け完了。
今後githubで進捗の管理ができる。

<h3>VSCodeを使用していく</h3>
ターミナル（hello-taroディレクトリ内で）

```
npm init -y
```
これでpackage.jsonが作成される

```javascript

{
  "name": "hello-taro",
  "version": "1.0.0",
  "description": "herokuでmysqlを扱う練習",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "githubのURLが記載"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/ユーザー名/hello-taro/issues"
  },
  "homepage": "https://github.com/ユーザー名#readme"
}
```
上記内容でファイルが作成される

```"main": "index.js",```
となっているがサーバー管理のファイル名を**app.jsなど別名にする時はapp.jsなどに変え**ておくと良さそう

<h3>express.jsとmysqlの準備</h3>
```
npm install express
```
を実行
（末尾の--saveは今はしなくてもデフォルトの様なので割愛。参考：[npm install --save について](https://qiita.com/takahiro_hata/items/056d2aeb636f343dadaf)）

各種モジュールの追加。package.jsonに

```
"dependencies": {
    "express": "^4.17.1"
```
が追加される。

mysqlのインストール

```
npm install mysql
```
packgage.jsonに
``` "mysql": "^2.18.1"```
が追加される。

※mysqlを扱うにはここでは割愛するが事前にhomebrewなどでmysqlをインストールする必要がある
参考：
https://reffect.co.jp/node-js/express-js-connect-mysql#MySQL-4
https://reffect.co.jp/laravel/mysql-laravel-in-mac

####コラム
package.jsonの記述を外からコピーしてきてnpm init を実行するとその記述に該当するモジュールをインストールできる様子（この部分はまだ怪しいところもある）

ここまでのpackage.json

```javascript
{
  "name": "hello-taro",
  "version": "1.0.0",
  "description": "herokuでmysqlを扱う練習",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ユーザー名/hello-taro.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/ユーザー名/hello-taro/issues"
  },
  "homepage": "https://github.com/ユーザー名/hello-taro#readme",
  "dependencies": {
    "express": "^4.17.1",
    "mysql": "^2.18.1"
  }
}
```

<h3>VSCodeでコードを書いていく</h3>


index.js

```javascript
const express = require('express')
var mysql = require('mysql')
const app = express()


var port = process.env.PORT || 5000;

app.get('/',(req, res)=>{
    
      res.send('helloえくすぷれす');
  })

app.listen(port, () => console.log(`Example app listening on port ${port}!`))
```

この記述で
```node index.js
```
をターミナルで実行するとポート5000番にて「helloえくすぷれす」が表示される
![スクリーンショット 2020-10-05 13.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/43c41ee4-72ce-8dc5-4069-6bb2cf8d50ff.png)

###解説
```
const express = require('express')
const mysql = require('mysql')
const app = express()
```

```const express = require('express')
```
でexpress.jsを扱い
```const mysql = require('mysql')```
でmysqlを扱っている。
**この辺りはデフォルト記述**

<h4>重要</h4>

```
var port = process.env.PORT || 5000;
```

ローカルの立ち上げではこの部分を
```var port = 3002```
で対応可能だが、herokuでのデプロイでは

```process.env.PORT || 5000;```
を使用する。

```
app.get('/',(req, res)=>{
    
      res.send('helloえくすぷれす');
  })

app.listen(port, () => console.log(`Example app listening on port ${port}!`))
```
ここではルート「/」にアクセスした時にhelloえくすぷれすを呼び出す記述をしている
app.listen()でポートの読み込み＆実行をしている。


**ここまででwebアプリのローカル側の記述は完成**


##②heroku公開（mysql不使用の状態）
**※事前にherokuの登録を完了しておく**
登録の内容は割愛（ググりでたくさん記事あり）

<h4>VSCodeにて新たにProcfileを作成</h4>
（Procfileとはherokuでサーバーを立ち上げる時に必要。
localでサーバーを立ち上げる記述である「node index.js」の内容を記述するファイル）

Procfile

```javascript
web: node index.js
```
Procfileと別でpackage.jsonのscriptに

```javascript
//今回この内容は使用しません
  "scripts": {
    "start":"node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
//今回この内容は使用しません
```
**※上記の様に記述している記事を見かけるが今回は不要※**


<h4>hello-taroディレクトリのターミナルにてherokuアプリを作成する</h4>

```

heroku login
heroku create hello-taro//ここのcrate以下の記載は任意（入力なしだとランダム名になる）
```
アプリが作成されるとherokuダッシュボードに作成したアプリ名が表示される
![スクリーンショット 2020-10-05 14.07.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/a739cae4-7b44-84db-88d6-47fd47954dee.png)


<h4>デプロイ</h4>
ターミナルにて

```
git add .
git commit -m '任意のコメント'
heroku git:remote -a hello-taro //hellotaro部分は自分のherokuのアプリ名を入れる
git push heroku master
```
成功するとターミナルに
![スクリーンショット 2020-10-05 14.24.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/65031065-3d31-344c-25ab-0a98b79d6070.png)
この様な記述が表示される。
``` https://hello-taro.herokuapp.com/ deployed to Heroku```
を⌘＋クリックで開くと公開されたhelloえくすぷれすが確認できる。

ちなみにgit push heroku masterがエラーの時はいったん、herokuではなくgithubの指定ブランチ（基本はmaster)にpushして最新にしてから再度
```git push heroku master```を試すと良い。

**以上でherokuのアップロード（mysql未使用）が完了**

##③herokuのclearDBを使用し、mysqlを使用可能にする
**※clearDBを使用するにはherokuで事前にクレジットカードの登録が必要**

<h4>clearDB導入〜herokuダッシュボードの対応</h4>
ターミナルにて

```
heroku addons:create cleardb:ignite
```
を実行
この操作でigniteプラン（clearDBの無料プラン）で登録がされる
無事に完了するとherokuダッシュボードの該当アプリのResourcesにclearDBが登録される
![スクリーンショット 2020-10-05 14.45.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/f9caf1e2-1cc3-af24-c00c-4b95d716c196.png)

さらにダッシュボードのSettingsを確認すると
![スクリーンショット 2020-10-05 14.51.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/1af383d4-56d7-545d-b91f-96cf84ef54ec.png)
この画面に遷移し、
中段のConfig VarsのReveal Config Varsを選択
![スクリーンショット 2020-10-05 14.51.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/7494cb42-4fe3-ddd4-7dab-c249cd4e2d3f.png)
上記画面が開く
ここで現状だと
```CLEARDB_DATABASE_URL```
のみ記述されていることを確認

**ターミナルに戻って**

```
heroku config | grep CLEARDB_DATABASE_URL
```
を実行。
この操作で現在のアプリで使用しているclearDBのmysqlの各項目の登録内容が確認できる
表示結果は以下

```
//ターミナル画面
あなたのmac@Mac hello-taro % heroku config | grep CLEARDB_DATABASE_URL
CLEARDB_DATABASE_URL: mysql://ユーザー名:パスワード@ホスト名/データベース名?reconnect=true
```
上記に表示の
```mysql://ユーザー名:パスワード@ホスト名/データベース名?reconnect=true```
をこれから使用していく。

ここでここで表示された
```mysql://ユーザー名:パスワード@ホスト名/データベース名?reconnect=true```
をコピーする

```
heroku config:set DATABASE_URL='mysql://ユーザー名:パスワード@ホスト名/データベース名?reconnect=true'
```
を実行する
成功すると
先ほどの画面にDATABASE_URLが追加される
![スクリーンショット 2020-10-05 15.04.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/eb863ffb-bced-a9a9-0b7f-c1033dba9fa2.png)

**以上でherokuダッシュボードの対応は完了**

<h4>DBの準備</h4>
ここからはtable plusというsql管理のGUIツールを使用する

事前に今回のアプリの内容を以下の様に整理しておくとこの後の記述が使いやすい

```
mysql://
bdc03c01341ef9 //ユーザー名
:
b01bd8f4 //パスワード
@
us-cdbr-east-02.cleardb.com //ホスト名
/
heroku_e21642c342a4850 //DB名
?reconnect=true
```

テーブルプラスを開き「Create a new connection」で新規接続を作る
![スクリーンショット 2020-10-05 15.12.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/db520003-b786-3e8d-3f56-ab9179c03a07.png)

mysqlを選択
![スクリーンショット 2020-10-05 15.12.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/c215e79a-011c-f673-1578-b7a84858c133.png)

Name：任意でOK（今回はディレクトリと同じ名前でhello-taroにした）
Host:herokuで登録のホスト名
User:herokuで登録のユーザー名
Password:herokuで登録のパスワード

以上を記入しConnectを選択
![スクリーンショット 2020-10-05 15.15.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/36dd03e8-6695-4cc0-5860-630325830086.png)


DB選択画面を選択すると自動的にherokuで作成したDB名が既に登録されているので、そのDBを選択しOpen
![スクリーンショット 2020-10-05 15.18.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/55f507da-26c7-c182-b636-6f1f5a6d81ea.png)

今回はhello太郎を表示させるためtestTableを作成する
![スクリーンショット 2020-10-05 15.21.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/518906a0-68a0-3dfd-f0b9-b5095686017e.png)

作ったtableのデータは上記の通り

テストデータを直接入力しておく
![スクリーンショット 2020-10-05 15.22.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/adae4e06-ee41-1983-c69b-70699c92ecd7.png)

**ここまででtable plusの準備は完了**

<h4>VSCodeでデータベース接続の記述を書く</h4>

index.jsを以下の様に変更する

```javascript
const express = require('express')
var mysql = require('mysql')
const app = express()

//ここを追加=============================
const connection =
   mysql.createConnection({
      host:'us-cdbr-east-02.cleardb.com',
      user:'bdc03c01341ef9',
      password:'b01bd8f4',
      database:'heroku_e21642c342a4850'
   });
//============================================


var port = process.env.PORT || 5000;

app.get('/',(req, res)=>{
//ここを追加===================================================
connection.query('SELECT * FROM test',(error,results)=>{
    res.send('hello'+results[0].name+':'+results[0].text);
      console.log(results)
      console.log(results[0])
      console.log(results[0].name)
      console.log(results[0].text)
  })
//===============================================
  })

app.listen(port, () => console.log(`Example app listening on port ${port}!`))
```

<h4>詳細説明</h4>
```
const connection =
   mysql.createConnection({
      host:'us-cdbr-east-02.cleardb.com',
      user:'bdc03c01341ef9',
      password:'b01bd8f4',
      database:'heroku_e21642c342a4850'
   });
```
ここにherokuのclearDBで取得した各値を入力

```
connection.query('SELECT * FROM test',(error,results)=>{
    res.send('hello'+results[0].name+':'+results[0].text);
      console.log(results)
      console.log(results[0])
      console.log(results[0].name)
      console.log(results[0].text)
  })
```
getの中の記述でSELECT文を使用しtestテーブルの値を取得。
取得した値は引数resultsに格納される
resultsの値をDBから取得し表示する必要があるため、コンソールで値が入っているか確認している。
取得した値は以下
![スクリーンショット 2020-10-05 15.34.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/0646d139-1fd3-14eb-653b-2024cc66f547.png)
先ほどtable plusで格納した値が取得できていることがわかる

この状態で```node index.js```
を実行すると、ポート5000番で
![スクリーンショット 2020-10-05 15.37.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/85dab517-d475-d2c2-0941-4aaf602964c8.png)
が表示される。

ローカルでのチェックは以上で完了。
ここからherokuにアップロードする。

方法は前述のherokuアップロードと同様

```
git add .
git commit -m '任意のコメント'
git push heroku master(ブランチ名は各自変更して下さい）
```

以上でプッシュが完了するとURLでも同様にhello太郎：優しいが表示される・

**以上でnode.js x express.js x mysqlアプリをherokuできました。**

ここを応用すれば更に大規模なアプリでも公開できるかと思います。


＃セッション使うアプリの時

```javascript
//heroku用
var serveStatic = require('serve-static');
app.use(serveStatic(__dirname + "/dist"));
```
この記述がapp.jsに必要そう