Node.jsとExpressのアプリで、データベースを使ってみる!node-postgresでHeroku Postgresを扱う方法!

データベースを使ってみよう!
  • URLをコピーしました!

今回は、Node.jsとExpressで作成したアプリケーションで、データベースを扱う方法を紹介していこうと思います。
アプリケーションを開発する上で、データベースは必須と言っても過言ではないくらい重要な内容です。

Node.jsとExpressアプリケーションでデータベースを扱う方法はいくつかあるのですが、今回は「node-postgres」でデータベースと接続していきたいと思っております。

学習に使った本はこちら!

¥3,740 (2022/12/04 09:33時点 | Amazon調べ)
¥2,851 (2022/12/04 09:34時点 | Amazon調べ)
クマじい

Amazon Kindle Unlimited でもNode.jsの本はいっぱいあるんじゃ!!

  • 技術書をたくさん読みたい!
  • 色々な技術を学びたい!
初回30日間無料体験があるので、どのような参考書があるか確認してみよう!

Kindle Unlimitedで技術書を読むならタブレットがあるとさらに便利ですよ!
10インチあるとより見やすいと思いますが、7インチでも十分見やすくなります!

¥15,980 (2022/12/09 11:28時点 | Amazon調べ)

もし、まだNode.jsとExpressでアプリを作った事がないと言う方は、下の記事を参考にしてみてください!

なるべく簡単に説明するように気をつけていますので、ぜひ参考にしてみてください!

こんな方に見て欲しい内容です!
  • nodeでデータベースを使ってみたい!
  • node-postgresの使い方が知りたい!
目次

データベース接続の準備をしよう!

クマじい

わしでも使えるかの〜?

では早速ですが、Nodeでデータベースを使えるようにしていこうと思います!
簡単ですので、安心してみてくれるといいと思います!

Nodeでデータベースにアクセスする方法は、大きく2通りあります。

  1. Sequelizeと言うORマッパーを使ってDBにアクセスする方法
  2. 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です!

Salesforce Platform 
DATA 
Datastores > postgresqI-crystaIIine-96768 
PLAN hobby-dev BILLING APP postgres-sample 
SERVICE heroku-postgresq 
Overview Durability Settings Dataclips 
ADMINISTRATION 
Database Credentials 
Get credentials for manual connections to this database. 
Please note that these credentials are not permanent. 
Heroku rotates credentials periodically and updates applications where this database is attached. 
Host 
Database 
User 
Port 
Password 
URI 
Heroku CLI

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;
localのpostgresを参照する場合
  • host:localhost
  • database:ご自身で登録したデータベース名
  • port:5432
  • user:ご自身で登録したユーザ名
  • password:ユーザのパスワード
SSLに関して

今回は、「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, 
text TEXT, 
: F,RlMåRY KEY Cid).

せっかくなので、このままデータも作ってしまいます!
idカラムは、serialと言う連番を自動採番してくれるデータ型になってますので、titleとtextのみを指定してinsertしたら大丈夫です!

INSERT 
INTO memo(title, text) 
VALUES ('test1', 'GETのテスト用データ');

SELECT文を実行して、このような結果になっていればOKです!

SELECT * FROM memo
1 
GET の テ ス ト 用 テ - タ

データベースからデータを取得できるようにする!

では、先ほど作成したデータを取得できるようにコードを書き換えていきましょう!
前回作成した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()を呼び出さなくていいのか。と言う疑問があるかもしれませんが、基本的に呼び出す必要はありません。

pool.end()はプールを使用する予定が無くなった場合に呼び出す必要がありますが、長時間実行され続けるアプリケーションの場合では、シャットダウンするときに呼び出すことになります。
その場合は、プールのソケットも閉じられるので無視しても問題がないです。

RestClientで確認してみよう!

では、アプリを起動してGETリクエストを送ってみましょう!
下の画像のように、先ほど作成したデータが取得できていればOKです!

METHOD 
GET 
HEADERS 
Ado neader 
Response 
2ee OK 
HEADERS 
X-Powered-8y: 
Content-Type: 
data : 
Content -Length 
ETag: 
Date 
Connection: 
Keep v e : 
SCHEME HOST [ PORT I [ PATH QUERY n 
http://localhost:3000/memo 
• QUERY PARAMETERS 
+ Add query parameter 
Add authorization 
Express 
application/3son; charset=utf-8 
72 bytes 
sun, 21 mar 2021 GMT 
keep- al 
timeout—5 
Form 
pretty 
BODY 
XHR does not allow payloads for GET request. 
BODY O 
4 send 
26 byte(s) 
Detected - 
id: 1, 
title 
: "testl" 
text : "GETd)i7 
O Top 
O Bottom 
Collapse 
a Open 
2Request 
copy 
Download

データベースにデータを登録しよう!

先ほどは、データベースのデータを取得しましたが、今回は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

データベースも見てみましょう!
下のように登録されているはずです!

id 
title 
6 日 の テ ス ト 用 デ - タ 
~ タ イ ト ル

まとめ

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

学習に使った本はこちら!

¥3,740 (2022/12/04 09:33時点 | Amazon調べ)
¥2,851 (2022/12/04 09:34時点 | Amazon調べ)
クマじい

Amazon Kindle Unlimited でもNode.jsの本はいっぱいあるんじゃ!!

  • 技術書をたくさん読みたい!
  • 色々な技術を学びたい!
初回30日間無料体験があるので、どのような参考書があるか確認してみよう!

Kindle Unlimitedで技術書を読むならタブレットがあるとさらに便利ですよ!
10インチあるとより見やすいと思いますが、7インチでも十分見やすくなります!

¥15,980 (2022/12/09 11:28時点 | Amazon調べ)

次回は、REST APIを実装していこうと思っています。
こちらでは、削除や更新のコードも載せるので参考にしてみてください。(詳しくは説明しないですが。。。)

データベースを使えれば、アプリケーション開発の幅が大きく広がりますのでぜひマスターしてみてください!

データベースを使ってみよう!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

東京在住で20代のエンジニアです。
特に特技があるわけではありませんが、誰もが楽しくプログラミングができたらいいと思い、「teech lab.」を開設いたしました。

Enjoy Diaryという、ガジェットや雑貨を紹介しているブログもあります!
ぜひ、みてください!!

目次