クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【Express】Fetch APIでAPIを叩いてHerokuのPostgreSQLのデータを表示する

Expressの続きです。前回はHerokuのPostgreSQLのデータをサーバ側のEJSファイルで読み込んでブラウザに表示しました。今回はブラウザ側からFetch APIでAPIを叩いてデータを表示します。それではいきましょう!

【目次】

※参考:前回記事
【Express】HerokuのPostgreSQLのデータを表示する - クモのようにコツコツと

※参考:Node.js / Expressを習得するためにやったことまとめ
qiita.com

前回のおさらい

HerokuのPostgreSQLのデータをブラウザに表示。サーバ側のEJSファイルで読み込んで作ったページ。 f:id:idr_zz:20201027153225j:plain

PostgreSQLの設定情報はHerokuの環境変数に設定しているため、GitHubのソース上にはない。

※参考:GitHub - ryo-i/Express-Heroku-Test at 42d9b23ca7d5dcf02c3003be3d8b2ba120272456

詳細は前回の記事を参照。

※参考:【Express】HerokuのPostgreSQLのデータを表示する - クモのようにコツコツと

今回はブラウザ側からFetch APIでAPIを叩いてデータを表示したい。

ブラウザ側のファイルを作成

「public」フォルダの中でブラウザ側のファイルを作る。 f:id:idr_zz:20201029195741j:plain

  • 「envTest.html」を複製し、「dbTest.html」に
  • 「js」フォルダの「script.js」を複製し、「dbTest.js」に

以前、Fetch APIで環境変数の値を読み込んだ。この時のファイルをベースにする。

※参考:【Express】Fetch APIでHerokuの環境変数を読み込んでブラウザに表示する - クモのようにコツコツと

HTMLファイルの内容

HTMLファイル(dbTest.html)の内容

dbTest.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PostgreSQL読み込みテスト</title>
</head>
<body>
    <section>
        <h1>PostgreSQL読み込みテスト</h1>
        <p>ここにPostgreSQLのデータを表示する</p>
        <ul class="dbTest"></ul>
        <p>GitHubとも連携していまぁす!</p>
    </section>
    <script src="js/dbTest.js"></script>
</body>
</html>
  • ulタグのclass名を.dbTestに変更
  • sctiptタグでdbTest.jsを読み込む

HTMLは変更はほとんどない。class名とjsのファイル名を変えているだけ。

JSファイルの内容

JSファイル(dbTest.js)

dbTest.js

const env = document.querySelector('.dbTest');
const url = '/dbTest';

// Read
const readFetch = () => {
    fetch(url).then((response) => {
        if(!response.ok) {
            console.log('Read error!');
            throw new Error('error');
        } 
        console.log('Read ok!');
        return response.text();
    }).then((data)  => {
        console.log(data);
        appendList(data);
    }).catch((error) => {
        console.log(error);
    });
};

readFetch();


// Append List
const appendList = (thisData) => {
    const li = document.createElement('li');
    li.innerHTML = 'こんにちは、' + thisData + 'さん!';
    env.appendChild(li);
};

JSファイルもほとんど変えずに済んでいて変更箇所はここ

const env = document.querySelector('.dbTest');
const url = '/dbTest';
  • 変数envで取得するDOMのclass名を.dbTestに変更
  • 変数urlのAPIのパスを/dbTestに変更

ブラウザ側はほぼ変更が不要ということだ!識別する名前が違うだけ。

これがフロントエンドとバックエンドの疎結合のメリット♪

ExpressファイルにAPI設定を追記

Expressの設定ファイル「index.js」に/dbTestパスのAPI設定を追記する。

前回の/dbパスのAPI設定のコードを改造している。

※参考:【Express】HerokuのPostgreSQLのデータを表示する - クモのようにコツコツと

index.js

  .get('/dbTest', async (req, res) => {
    try {
      const client = await pool.connect()
      const result = await client.query('SELECT * FROM member');
      const name = result.rows[0].name;
      console.log('name->' + name);
      res.send(name);
      client.release();
    } catch (err) {
      console.error(err);
      res.send("Error " + err);
    }
  })
  • get()メソッドの第一引数はパスで/dbTest
    第二引数はasync/await構文で無名関数を実行(引数はreq, res
  • 無名関数の処理はtry...catch文を実行
    tryでは変数clientpoolconnect()
    その後(await)、変数resultclientからSELECT文でテーブルmemberのデータを読み込む
    変数nameresultの1行目rows[0]nameカラムを取得
    console.log()でターミナルにnameを表示
    res.sendr()nameを返す
    client.release()を実行
  • catch()の引数はerr
    コンソールにエラー内容errを表示
    res.send()で「Errorエラー内容err」というレスポンスを返す

主な変更点は

  • パスを/dbTestに変更
  • 変数nameで1行目のnameを決め打ちで取得している
  • そのname自体をres.send()で直接返している

想定通りに行けば以前こちらの記事で作ったmemberテーブルの1行目のnameである「ジョン・レノン」を返してくれるはず。

※参考:【SQL】ターミナルからHerokuのPostgreSQLにCRUDする - クモのようにコツコツと


なお、pgモジュールの設定を書く上で下記のドキュメントを参考にした。

※参考:Welcome | node-postgres

※参考:Extras · brianc/node-postgres Wiki · GitHub

※参考:FAQ · brianc/node-postgres Wiki · GitHub

ちなみにExpressのドキュメントにもPostgreSQLの使用例があったが「pg-promise」というモジュールを使っているのでちょっと書き方が違った。

※参考:Express database integration

ローカル環境で動作確認する

まずはローカル環境で動作確認してみる。

Herokuのサーバを起動

$ heroku local web

http://localhost:5000/dbTest.html」にアクセスする。

おお、名前が「ジョン・レノン」になっている!成功だ! f:id:idr_zz:20201029195757j:plain


Dev-Toolsの「Console」を開くとFetch APIで設定したログが表示されている。

Read ok!
ジョン・レノン

ターミナルでもExpressで設定したログが表示されている。

name->ジョン・レノン

Dev-ToolsのNetworkを確認。Fetch APIが「/dbTest」パスを叩いている。 f:id:idr_zz:20201030055704j:plain

APIのパスからはPostgreSQLのデータ「ジョン・レノン」が返って来ている。 f:id:idr_zz:20201030055827j:plain

実際に「http://localhost:5000/dbTest」を開いてみる。値が画面に表示されている♪ f:id:idr_zz:20201030055938j:plain

次はリモートのHerokuアプリで動作確認したい。

一旦「Control + C」でサーバを閉じる。ターミナルの行頭が$に戻る。

GitHubに変更内容をプッシュ

リモートのHerokuアプリに変更を反映する。以前、GitHubとHerokuを連携しているので、コミットをGitHubにプッシュすれば良い。

※参考:【Express】HerokuとGitHubを連携して自動デプロイ(環境変数は除外) - クモのようにコツコツと

下記の3つのコマンドでコミットをGitHubにプッシュする。

$ git add .
$ git commit -m "「dbTest」を追加"
$ git push -u origin main

GitHubを確認。変更が反映された! f:id:idr_zz:20201030060637j:plain

※参考:「dbTest」を追加 · ryo-i/Express-Heroku-Test@bef283f · GitHub

Herokuアプリで動作確認

次にHerokuアプリを開く。

こちらも名前が「ジョン・レノン」になっている! f:id:idr_zz:20201029195814j:plain

※参考:http://aqueous-mountain-80366.herokuapp.com/dbTest.html

Dev-Toolsの「Network」を確認。Fetch APIが「/dbTest」パスを叩いて… f:id:idr_zz:20201030063701j:plain

PostgreSQLのデータ「ジョン・レノン」が返って来ている。 f:id:idr_zz:20201030063815j:plain

APIのパスを開くと「ジョン・レノン」が表示される。 f:id:idr_zz:20201030061607j:plain

※参考:http://aqueous-mountain-80366.herokuapp.com/dbTest

PostgreSQLの接続情報はHerokuの環境設定に設定されているのでGitHub上には含まれていない!

※参考:GitHub - ryo-i/Express-Heroku-Test at bef283fc2e230d4e104548f81201f00fd4577e6b

最後に

ということでブラウザ側のFetch APIからExpressのAPIを叩いてPostgreSQLのデータを表示することができました。PostgreSQLの設定はHerokuの環境変数に設定しているのでGitHubのソースには含まれていません。

次回はブラウザのフォームと連携してPostgreSQLにCRUD処理をしたく思います。地道にコツコツ進めていますが、これまでやって来た点と点がだんだんと繋がって来てる感じがして来ましたー。

それではまた!


※参考:Node.js / Expressを習得するためにやったことまとめ
qiita.com