node.js Webアプリケーション作成(2018基礎）

node.jsとPostgreSQLを使ったWebアプリケーションの基本部分をDebian Stretchを使って紹介する。この記事では、セッション管理・HTMLテンプレートやWebアプリケーションフレームワークを使用しない。
#前準備

- インストール
node.jsとPostgreSQLの接続ライブラリをインストールする。他にもPostgreSQL本体のインストールが別途必要だ。

```bash:
#npm node.jp用ライブラリのパッケージ管理ツール
sudo apt install npm
#n node.jsそのもののバージョン管理ツール
sudo npm install -g n
sudo n stable
#pg PostgreSQL用のライブラリ
sudo npm install pg

```

#データベース
操作するデータベースとユーザーの生成を次に示す。

 - DB認証情報の設定

```
export dbadmin=postgres        #データベースを作れるDB管理者
export dbname=使用するデータベース名 
export username=DBユーザー名     
```
 - データベースとユーザーの作成
 
```bash:
sudo -E su $dbadmin
createuser -P  $username  #設定するパスワードをメモ 
createdb -O $username $dbname
exit
export PGPASSWORD=パスワード #上記で設定したパスワード

```

 - データベースとユーザーの削除

誤ってしまった場合やデータベースとそのユーザーが不要になった場合は、次の操作でDBとユーザーを削除する。

```bash:createdb
sudo -E su $dbadmin
dropdb $dbname
dropuser $username
exit
```

 - DB接続
次のpsqlコマンド接続することが出来る。

```
psql $dbname $username -h 127.0.0.1
```
- スキーマとデータ

```sql:sample.sql
create table member (
  id    serial PRIMARY KEY,  --serialは自動採番型
  name  TEXT NOT NULL,
  age   int,
  height  numeric(4,1)       --整数部3桁小数部1桁
);

insert into member (name,age,height) values('太郎',12,124.1);
insert into member (name,age,height) values('花子',14,110.3);
```


#プログラム

 - 接続情報を環境変数に書き出すスクリプト
認証情報はソースコードに直接書いても動作するが、接続情報は環境変数に入れて使うことが多い。前節で設定したデータベースの認証情報などを記述する。

```bash:env.sh
##!/bin/bash ##このスクリプトは. env.shで実行させる。
export dbname=データベース名
export username=データベースユーザ名
export userpassword=パスワード
export host=127.0.0.1
export dbConnectStr=tcp://$username:$userpassword@$host/$dbname
```
 - 本体
 
 アクセス元IPアドレス制限なし、ポート3000で設定した。

```javascript:dbweb.js
"use strict";

const http = require('http');
const hostname = '0.0.0.0';
const port = 3000;
const backlog = 500;
const server = http.createServer();
const pg = require('pg');
const dbConnectStr = process.env.dbConnectStr;

server.on('request', function(req, res) {
    const client = new pg.Client(dbConnectStr);
    client.connect(function(err) {
        if (err) {
            return console.error('could not connect to postgres', err);
        }
        client.query('select id, name,age,height from member order by id;', function(err, result) {
            if (err) {
                return console.error('could not connect to postgres(query)', err);
            }
            res.writeHead(200, {
                'Content-Type': 'text/html; charset=UTF-8'
            });
            for (const data of result.rows) {
                const id = data.id;
                const name = data.name;
                const age = data.age;
                const height = data.height;
                res.write("id:" + id);
                res.write("<br>");
                res.write("name:" + name);
                res.write("<br>");
                res.write("age:" + age);
                res.write("<br>");
                res.write("height:" + height);
                res.write("<hr>");
            }
            const date = new Date();
            res.write(date.toString());
            res.end();
        });
        client.on('drain', client.end.bind(client));
    });
});

server.listen(port, hostname, backlog, function() {
    console.log(`Server runnning at http://${hostname}:${port}/`);
// 接続情報を表示確認する場合 以下を有効にする。
//  console.log(`dbConnectStr ${dbConnectStr}`); 
});
```

#実行方法

```bash:
. env.sh
node dbweb.js
```
あとはWebブラウザでhttp://(IPアドレス):3000にアクセスすれば良い。

![output.png](https://qiita-image-store.s3.amazonaws.com/0/171932/32e3eb91-17fe-2b9a-ba64-545a5c77b57b.png)


#参考サイト
 - [PostgreSQLにテストデータを作成するnode.jsスクリプト](
https://qiita.com/fujisan3/items/dc461b75d3a351309f3e)
 - [今さらnode-postgres案内(2)　後始末の流儀 - client.end()とclient.on 'drain'](
https://qiita.com/mrpepper/items/0ee6bbcf9743a9a3931d)