07.Heroku Demo作成（Node JS）

#0.準備条件
1. Salesforce 組織
2. Heroku
    - Web Application 
    - Heroku Connect （取引先のMapping設定）
    - Heroku Postgres

#1.Node.js 実装 Resource 構成
- routes
    - account.js 
- views
    - account.ejs
    - accountList.ejs
- app.js
- package.json
- Procfile

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/6475d397-e73a-ec66-0d80-f0810707b665.png)

#2.account.js 
```javascript

var express = require('express');
var router = express.Router();
const { Pool } = require('pg');
const pool = new Pool({
    connectionString: process.env.DATABASE_URL,
    ssl: true
});

router.get('/', (req, res, next) => {
    // 登録したら一覧に戻る
    res.redirect('/account/list');
});

router.get('/new', (req, res, next) => {
    res.render('account');
});

router.post('/save', async(req, res, next) => {
    // 登録内容をフォームから引っこ抜く
    const name = req.body.name;
    const phone = req.body.phone;
    const fax = req.body.fax;
    const accountUUID = req.body.accountUUID;

    // 取引先を新規登録する
    const client = await pool.connect();
    const insertData = {
        text: 'insert into salesforce.account (name, phone, fax, accountuuid__c) values ($1, $2, $3, $4)',
        values: [name, phone, fax, accountUUID],
    }
    const result = await client.query(insertData);
    client.release();

    // 登録したら一覧に戻る
    res.redirect('/account/list');
});

router.get('/list', async(req, res, next) => {
    const client = await pool.connect();
    const result = await client.query('select * from salesforce.account order by id DESC');
    const results = { 'results': (result) ? result.rows : null};
    client.release();

    res.render('accountList', results);
});

module.exports = router;

```

#3.account.ejs
```html

<!DOCTYPE html>
<html>
  <head>
    <title>登録</title>
  </head>
  <body>
      <h1>新規取引先</h1>
        <form action="/account/save" method="POST">
            <table>
                <tr>
                    <th>取引先名</th>
                    <td>
                        <textarea name="name"></textarea>
                    </td>
                </tr>
                <tr>
                    <th>電話</th>
                    <td>
                        <textarea name="phone"></textarea>
                    </td>
                </tr>
                <tr>
                    <th>Fax</th>
                    <td>
                        <textarea name="fax"></textarea>
                    </td>
                </tr>
                <tr>
                    <th>取引先UUID</th>
                    <td>
                        <textarea name="accountUUID"></textarea>
                    </td>
                </tr>
                <tr>
                    <th></th>
                    <td>
                        <button type="submit">保存</button>
                    </td>
                </tr>
        </table>
        </form>
  </body>
</html>
```

#4.accountList.ejs
```html

<!DOCTYPE html>
<html>
  <!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
  <head>
    <title>取引先一覧</title>
  </head>
  <body>
    <div class="container">
      <div class="row">
        <div class="col">
    <h1>取引先情報</h1>
  </div></br>
  <div class="col-md-12">
        <a href="/account/new">新規追加</a>
        <br>
      </div>
      <br>
      <table class="table table-bordered">
        <thead class="thead-dark">
          <tr>
            <th scope="col">No</th>
            <th scope="col">取引先名</th>
            <th scope="col">電話</th>
            <th scope="col">Fax</th>
            <th scope="col">取引先UUID</th>
          </tr>
        </thead>
        <tbody>

        <% for(var i=0; i<results.length; i++) {%>
          <tr>
            <td><%= results[i].id%></td>
            <td><%= results[i].name%></td>
            <td><%= results[i].phone%></td>
            <td><%= results[i].fax%></td>
            <td><%= results[i].accountuuid__c%></td>
          </tr>
          <% } %>

    </tbody>
  </table>

      </div>
    </div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.bundle.min.js" integrity="sha384-zDnhMsjVZfS3hiP7oCBRmfjkQC4fzxVxFhBx8Hkz2aZX8gEvA/jsP3eXRCvzTofP" crossorigin="anonymous"></script>
  </body>
</html>
```
#5.app.js
```javascript

var express = require('express');
var bodyParser = require('body-parser');
 
// express の実態 Application を生成
var app = express();
app.set('port', process.env.PORT || 3000);

// urlencodedとjsonは別々に初期化する
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

// テンプレートエンジンを EJS に設定
app.set('views', './views');
app.set('view engine', 'ejs');
 
// 静的ファイルは無条件に公開
app.use('/public', express.static('public'));
 
// ルーティング設定
app.use('/', require('./routes/account.js'));
app.use('/account', require('./routes/account.js'));
 
// アプリケーション開始ログ
app.listen(app.get('port'), function () {
    console.log('Express server listening on port ' + app.get('port'));
});
```

#6.package.json
```json
{
  "name": "a03",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "dotenv": "^8.2.0",
    "ejs": "^3.1.2",
    "express": "^4.17.1",
    "pg": "^7.18.2"
  },
  "engines": {
    "node": "12.1.0",
    "npm": "6.12.1"
  }
}

```

#7.Procfile
```
web: node app.js
```
#8.画面イメージ
**取引先情報一覧画面**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/f2185013-b365-94f0-4c85-6f7fac182178.png)


**取引先情報新規登録画面**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/1f791e49-52b6-ccae-e06a-41022cf7918c.png)