今回は、Node.jsとExpressで作成したアプリケーションで、データベースを扱う方法を紹介していこうと思います。
アプリケーションを開発する上で、データベースは必須と言っても過言ではないくらい重要な内容です。
Node.jsとExpressアプリケーションでデータベースを扱う方法はいくつかあるのですが、今回は「node-postgres」でデータベースと接続していきたいと思っております。
学習に使った本はこちら!



Amazon Kindle Unlimited でもNode.jsの本はいっぱいあるんじゃ!!
もし、まだNode.jsとExpressでアプリを作った事がないと言う方は、下の記事を参考にしてみてください!




なるべく簡単に説明するように気をつけていますので、ぜひ参考にしてみてください!
- nodeでデータベースを使ってみたい!
- node-postgresの使い方が知りたい!
データベース接続の準備をしよう!



わしでも使えるかの〜?
では早速ですが、Nodeでデータベースを使えるようにしていこうと思います!
簡単ですので、安心してみてくれるといいと思います!
Nodeでデータベースにアクセスする方法は、大きく2通りあります。
- Sequelizeと言うORマッパーを使ってDBにアクセスする方法
- pg(node-postgres)を使って、SQLを書いてDBに接続する方法です。
Sequelizeは、SQLを書く必要がなかったり、マイグレーションができたりと便利なのですが、少し学習コストがかかります。
今回は、SQLの学習というところも兼ねてpg(node-postgres)で実装していきます!
「node-postgres」をインストールしよう!
早速、「node-postgres」をインストールしていきます。
インストール手順は、こちらの公式ページにある通りです!
コマンドで「npm install pg」を実行するだけでインストールできます!
C:\Users\*****\Documents\sample>npm install pg
+ pg@8.5.1
added 19 packages from 11 contributors and audited 120 packages in 7.945s
実行できたら、インストールできたか確認してみましょう!
package.jsonに「pg: “バージョン”」が追記されていれば大丈夫です!
package.json
{
"name": "sample",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"morgan": "~1.9.1",
"pg": "^8.5.1"
}
}
接続プールを実装しよう!
続いて接続プールを実装していきます。
公式のページでは、Clientを使って実装していますが、毎回新しいクライアントでPostgreSQLに接続する場合、handshakeで毎回時間がかかってしまいます。
それだと、アプリケーションの速度が大幅に低下してしまう可能性があります。
Poolを使えば、クライアントを再利用することでこの辺の時間を短縮することができます。
詳しくは、こちらで確認してみてください。
では、実装していきましょう!
まず、アプリのディレクトリ直下に任意ディレクトリを作成してください!(今回は、dbとしています。)
次に、db配下に、「pool.js」を作成してください!
できたらこんな感じの構成になっていると思います!


pool.jsには、DBの接続情報ををもったプールを実装していきます!
もし、まだDB環境を構築できていない方がいれば、こちらの記事を参考にHerokuでPostgresを構築していただくか、ローカルにPostgresをインストールしてみてください!
今回は、Heroku Postgresを用いて説明していきます。


では、pool.jsを編集していきましょう!
基本的には、下記を参考にしてもらえればいいのですが、「host」や「database」などの情報は、各自の情報を入力してください!
Heroku Postgresの場合は、下記の画面の情報を入力してもらえればOKです!


pool.js
const { Pool } = require("pg");
// DB情報をもったプールを生成
const pool = new Pool({
host: '[HOST]',
database: '[DATABASE]',
port: 5432,
user: '[USER]',
password: '[PASSWORD]',
ssl: {
sslmode: 'require',
rejectUnauthorized: false
}
});
module.exports = pool;
- host:localhost
- database:ご自身で登録したデータベース名
- port:5432
- user:ご自身で登録したユーザ名
- password:ユーザのパスワード
今回は、「rejectUnauthorized: false」に設定しています。
これは証明書検証を無視する設定ですが、本来はあまり好ましくありません。
Heroku Postgresの無料環境では、証明書が非対応とのことでこの設定になっています。
個人での勉強レベルなら問題ないと思いますが、商用等の際は注意をしてください。
今回は、「sslmode: ‘require’」を設定しています。
具体的には、
- 接続は暗号化されており、盗聴からは保護される
- 中間者(MITM)攻撃から保護されていない
と言う感じです。


データベースからデータを取得しよう!
では、実際にデータベースからデータを取得していこうと思います!
データベースにデータを作る!
まずは、データベースに取得するデータを作っておこうと思います。
今回は、メモを取得するAPIを作っていこうと思いますので、メモテーブルを作成します。
CREATE TABLE memo(
id serial
, title TEXT
, text TEXT
, PRIMARY KEY (id)
);
A5M2だと、こんな感じで実行したら大丈夫です!


せっかくなので、このままデータも作ってしまいます!
idカラムは、serialと言う連番を自動採番してくれるデータ型になってますので、titleとtextのみを指定してinsertしたら大丈夫です!
INSERT
INTO memo(title, text)
VALUES ('test1', 'GETのテスト用データ');
SELECT文を実行して、このような結果になっていればOKです!
SELECT * FROM memo


データベースからデータを取得できるようにする!
では、先ほど作成したデータを取得できるようにコードを書き換えていきましょう!
前回作成したmemo.jsからDBに接続してSELECTできるようにしていきます!
memo.js
var express = require('express');
var router = express.Router();
// pool.jsを読み込み
const pool = require('../db/pool');
// memoテーブルの全データを返却するAPI
router.get('/', function (req, res, next) {
// SELECT
pool.query('SELECT * FROM memo', function(error, results){
// エラーの場合
if (error) {
throw error
}
// 正常なら取得したデータを返却
res.status(200).json({
data: results.rows
});
});
});
// memoをPOSTで受け取る
router.post('/', function (req, res, next) {
console.log(req.body)
res.json({
id: req.body.memo.id,
text: req.body.memo.text,
});
});
module.exports = router
pool.end()を呼び出さなくていいのか。と言う疑問があるかもしれませんが、基本的に呼び出す必要はありません。
pool.end()はプールを使用する予定が無くなった場合に呼び出す必要がありますが、長時間実行され続けるアプリケーションの場合では、シャットダウンするときに呼び出すことになります。
その場合は、プールのソケットも閉じられるので無視しても問題がないです。
RestClientで確認してみよう!
では、アプリを起動してGETリクエストを送ってみましょう!
下の画像のように、先ほど作成したデータが取得できていればOKです!


データベースにデータを登録しよう!
先ほどは、データベースのデータを取得しましたが、今回はPOSTで受け取ったデータをデータベースに登録すると言うことをやってみようと思います!
データをデータベースに登録できるようにする!
memo.jsのPOSTの部分を修正していきます!
基本的な修正内容は、GETと同じなので一度見ずに実装してみてもいいかもしれません。
memo.js
var express = require('express');
var router = express.Router();
// pool.jsを読み込み
const pool = require('../db/pool');
// memoテーブルの全データを返却するAPI
router.get('/', function (req, res, next) {
// SELECT
pool.query('SELECT * FROM memo', function(error, results){
// エラーの場合
if (error) {
throw error
}
// 正常なら取得したデータを返却
res.status(200).json({
data: results.rows
});
});
});
// memoをPOSTで受け取る
router.post('/', function (req, res, next) {
// bodyからtitleとtextを取得
const {title, text} = req.body.memo;
// titleとtextを引数にして、登録する
pool.query('INSERT INTO memo(title, text) VALUES ($1, $2)', [title, text], function(error, results) {
if(error) {
throw error;
}
// 登録できたらsuccessを返却
res.status(201).json({
status: 'success',
});
})
});
module.exports = router
RestClientで確認してみよう!
こちらもRestClientで確認していきましょう!
Bodyの内容は、下でリクエストを送ってみます!
{
"memo": {
"title": "タイトル",
"text": "POSTで登録"
}
}
RestClientで、下のようになればOKです!
![METHOD
HEADERS
Content-Type
SCHEME HOST [ PORT I [ PATH QUERY n
http://locaIhost:3000/memo
QUERY PARAMETERS
Adc query parameter
application/json
Form
pretty
BODY
Ada neader 1 Add authorization
Terro :
"title": "
"text "
Text HTML I body I evaluation
4 send
length: 26 byte(s)
Text
76 bytes
Cadie Detected • Elapsed Time: I S9s
Response
2e1 Created
HEADERS
X- Powered - By :
Content-Type:
Content •Length :
ETag:
Expre s s
application/'son;
20 bytes
W/"14.YS3wuE/mmbSikKcT/Wua1LIN6SU"
sun, 21 mar 2e21 13:21:22 GMT -Is
BODY
status :
"success"
O Top
O Bottom
collapse
a open
2Reguest
Q] copy
Download](https://teech-lab.com/wp-content/uploads/2021/03/image-53-1024x453.png)
![METHOD
HEADERS
Content-Type
SCHEME HOST [ PORT I [ PATH QUERY n
http://locaIhost:3000/memo
QUERY PARAMETERS
Adc query parameter
application/json
Form
pretty
BODY
Ada neader 1 Add authorization
Terro :
"title": "
"text "
Text HTML I body I evaluation
4 send
length: 26 byte(s)
Text
76 bytes
Cadie Detected • Elapsed Time: I S9s
Response
2e1 Created
HEADERS
X- Powered - By :
Content-Type:
Content •Length :
ETag:
Expre s s
application/'son;
20 bytes
W/"14.YS3wuE/mmbSikKcT/Wua1LIN6SU"
sun, 21 mar 2e21 13:21:22 GMT -Is
BODY
status :
"success"
O Top
O Bottom
collapse
a open
2Reguest
Q] copy
Download](https://teech-lab.com/wp-content/uploads/2021/03/image-53-1024x453.png)
データベースも見てみましょう!
下のように登録されているはずです!


まとめ
今回は、pgを使ってデータベースからデータを取得する方法とデータベースにデータを登録する方法を解説致しました。
削除や更新は、今回の内容を応用してもらえれば簡単にできると思いますので、各自でやってみてはいかがでしょうか!
学習に使った本はこちら!







Amazon Kindle Unlimited でもNode.jsの本はいっぱいあるんじゃ!!
次回は、REST APIを実装していこうと思っています。
こちらでは、削除や更新のコードも載せるので参考にしてみてください。(詳しくは説明しないですが。。。)
データベースを使えれば、アプリケーション開発の幅が大きく広がりますのでぜひマスターしてみてください!