クモのようにコツコツと

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

【Express】MySQLのデータをbody-parserでブラウザに返す

Expressの続きです。前回はBody-parserを使ってFetch API(およびFormタグ)のデータを受け取りました。今回はさらにMySQLのデータをブラウザに返す動きを体験したく。それではいきましょう!

【目次】

※参考:前回記事
【Express】body-parserでFetch API(およびForm)のPOST送信を受け取る - クモのようにコツコツと

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

前回のおさらい

FormタグとFetch APIからデータを送信。Expressのbody-parserでデータを受け取ってまた返す。 f:id:idr_zz:20200830092152j:plain Fetch APIの場合はページ遷移やリロードせずにアラートを表示できた!

※参考:前回記事
【Express】body-parserでFetch API(およびForm)のPOST送信を受け取る - クモのようにコツコツと

今回はMySQLとbody-parserの連携を行いたい。MySQLとExpressの連携は以前こちらの記事で行った。

f:id:idr_zz:20200816173532j:plain

※参考:【Epxress】データベース接続の比較(MySQLとMongoDB) - クモのようにコツコツと

この時はconsole.log()でターミナルにデータを表示したのみだが、今回はbody-parserでデータをブラウザに返したい。

body-parserの設定

まず、前回と同様にexpressとbody-parserをインストール。手順はこちらを参照。

※参考:前回記事
【Express】body-parserでFetch API(およびForm)のPOST送信を受け取る - クモのようにコツコツと

次にHTML部分を以前のJSON Serverの記事の時のように、Fetch API部分のみにする(今日の一句)。

※参考:【JS】Fetch APIを使ってJSON ServerにCRUDする - クモのようにコツコツと

index.html

    <section>
        <h1>今日の一句</h1>
            <section>
                <h2>一句詠む</h2>
                    <input type="text" name="ikku" size="30" maxlength="30" class="postIkku">
                    <input type="button" value="送信" class="postBtn">      
            </section>
            <section>
                <h2>過去の一句</h2>
                <ul class="ikkuList"></ul> 
            </section>
    </section>

一句を読むのinputタグ(name属性がikku)に修正

fetch_crud.js

const postIkku = document.querySelector('.postIkku');
const postBtn = document.querySelector('.postBtn');
const ikkulist = document.querySelector('.ikkuList');
const url = '/fetch';

const postFetch = () => {
    const formData = {
        ikku: postIkku.value
    };

    fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
    }).then((response) => {
        if(!response.ok) {
            console.log('error!');
        }
        console.log('ok!');
        console.log(response);
        return response.text();
    }).then((data)  => {
        console.log(data);
        alert(data);
    }).catch((error) => {
        console.log(error);
    });
};

postBtn.addEventListener('click', postFetch, false);

Fetch APIの設定。postFetchikkuキーでpostIkkuの入力値valueを送信する。

index.js

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

app.use(express.static('public'));

// Fetch API設定
const jsonParser = bodyParser.json();
 
app.post('/fetch', jsonParser,  (req, res) => {
    console.log(req.body);
    const ikku = req.body.ikku;
    console.log('ikku->' + ikku);
    res.send('今日の一句:' + ikku);
});

app.listen(3000, () => {
    console.log('Start server port:3000');
});

Formタグの設定は削除。Fetch API設定のres.send ()ikkuキーのデータを返す。

※参考:GitHub - ryo-i/express_mysql_bp at 0bbd701b0e864b004adf7e2f4d9962b2d69a2d99

nodemonで起動。

nodemon index.js

ブラウザでlocalhost(ポート番号3000)を開くと一句のフォームが表示されてる! f:id:idr_zz:20200902070907j:plain

一句を入れて送信すると… f:id:idr_zz:20200902070911j:plain

アラートで一句が表示された! f:id:idr_zz:20200902070913j:plain

Dev-toolsのNetworkを確認。 f:id:idr_zz:20200902070916j:plain

Headersの下の方を見ると一句が送信されている。 f:id:idr_zz:20200902070919j:plain

Responseを見ると一句が返されていることがわかる。 f:id:idr_zz:20200902070922j:plain Fetch APIがこのレスポンスのデータをアラートに入れている。

MySQLのデータベース作成

次はMAMPのMySQLにデータベースを追加する。以前のこちらの記事でやった手順にて。

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

まず新規データベースikkuを作成し

CREATE DATABASE ikku;

新規テーブルikkulist作成

CREATE TABLE ikkulist (
    id MEDIUMINT NOT NULL AUTO_INCREMENT,
    ikku VARCHAR(100),
    PRIMARY KEY (id)
);

INSERT文でデータも1件する

INSERT INTO ikkulist (ikku) VALUES (
    'JSや ああJSや JSや'
);

MAMPのphpMyAdminを確認すると、一句「JSや ああJSや JSや」が追加されてる!! f:id:idr_zz:20200902071046j:plain

ExpressとMySQLの連携

最後にMySQLとExpressを連携する。こちらの記事の手順にて。

※参考:【Epxress】データベース接続の比較(MySQLとMongoDB) - クモのようにコツコツと

MySQLのモジュールをインストール

npm install mysql

MAMPのMySQLのデータベース設定

// MySQL設定
const connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'ikku',
    port: 8889
});

次にMySQLと接続設定

    connection.query('SELECT id, ikku FROM ikkulist',
    (err, result) => {
      if (err) throw err;
      const resIkku = result[0].ikku;
      console.log('resIkku->' + resIkku);
      const resText = '今日の一句:' + resIkku;
      res.send(resText);
    });
  • connection.query()の第一引数はSELECT文でikkuのデータを読み込み
  • 第二引数は無名関数。引数でエラーか成功の結果を取得
  • エラーの場合は処理を抜ける
  • 変数resIkkuで結果の配列1行目(レコード)のikku 列(カラム)のデータ(フィールド)を取得
  • コンソール(ターミナル)にresIkkuを表示
  • res.send()resIkkuをブラウザに返す

res.send()でデータresTextをブラウザに返すのが今回のキモ!

なお、データは配列の中に連想配列(オブジェクト)で入る形式のため、配列数[0]が1行目のレコード、キーikkuがカラム名の意味になる。

また、下記の記事のようにconnection.query()メソッド単独でも(DBへの接続connection.connect()、解除connection.end()はなしで)処理が実行された!

※参考:Express.js(node.js)からMySQLへの接続とCRUD操作 | アールエフェクト

動作確認。「Reactや ああReactや Reactや」という一句を送信すると… f:id:idr_zz:20200903065220j:plain

「今日の一句:JSや ああJSや JSや」というアラートが表示された! f:id:idr_zz:20200903065223j:plain

Dev-toolsのNetworkを確認。 f:id:idr_zz:20200903065227j:plain

Headersの下の方。inputタグに入れた「Reactや〜」を送信しているが… f:id:idr_zz:20200903065230j:plain

ResponseはMySQLのデータ「JSや〜」が返されていることがわかる。 f:id:idr_zz:20200903065232j:plain

今のままではフォームの入力とレスポンスには整合性がない。ここに整合性を持たせるにはデータベースへのCRUD処理が必要になってくる。

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

今回作ったコード

今回作ったコード全体

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ExpressでMySQLとbody-parser連携</title>
    <link rel="stylesheet" href="css/fetch_crud.css">
</head>
<body>
    <section>
        <h1>今日の一句</h1>
            <section>
                <h2>一句詠む</h2>
                    <input type="text" name="ikku" size="30" maxlength="30" class="postIkku">
                    <input type="button" value="送信" class="postBtn">      
            </section>
            <section>
                <h2>過去の一句</h2>
                <ul class="ikkuList"></ul> 
            </section>
    </section>
    <script src="js/fetch_crud.js"></script>
</body>
</html>

ブラウザのフォーム設定。CSS設定もあるけど省略

fetch_crud.js

const postIkku = document.querySelector('.postIkku');
const postBtn = document.querySelector('.postBtn');
const ikkulist = document.querySelector('.ikkuList');
const url = '/fetch';

const postFetch = () => {
    const formData = {
        ikku: postIkku.value
    };

    fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
    }).then((response) => {
        if(!response.ok) {
            console.log('error!');
        }
        console.log('ok!');
        console.log(response);
        return response.text();
    }).then((data)  => {
        console.log(data);
        alert(data);
    }).catch((error) => {
        console.log(error);
    });
};

postBtn.addEventListener('click', postFetch, false);

Fetch APIの設定

index.js

const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser');
const app = express();

app.use(express.static('public'));


// MySQL設定
const connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'ikku',
    port: 8889
  });


// Fetch API設定
const jsonParser = bodyParser.json();
 
app.post('/fetch', jsonParser,  (req, res) => {
    console.log(req.body);
    const ikku = req.body.ikku;
    console.log('ikku->' + ikku);

    connection.query('SELECT id, ikku FROM ikkulist',
    (err, result) => {
      if (err) throw err;
      const resIkku = result[0].ikku;
      console.log('resIkku->' + resIkku);
      const resText = '今日の一句:' + resIkku;
      res.send(resText);
    });

});

app.listen(3000, () => {
    console.log('Start server port:3000');
});

ブラウザからリクエストを受けてMySQLの1行目のデータをレスポンスとして返す。

GitHub

※参考:GitHub - ryo-i/express_mysql_bp: Expressを使ってMySQLとbody-parserを連携する

最後に

ということで、MySQLのデータをbody-parserを使ってブラウザに返すことができました!今の状態ではフォームとDBにまだ整合性がないため、次はいよいよフォームとDBを連携したCRUD処理を行いたく思います!

自分的にはこれまで個別で行ってきたピースがだんだんと合体しつつあるので、これまでのもどかしかった気持ちがワクワクに変わってきています♪(本当はブラウザとDBのCRUD処理までを1記事くらいで実現したかったが自分の理解度では一気には無理だった…)

それではまた!


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