24
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[node.js] Express,mysql2/promiseでasync/await使って簡潔に書く

Last updated at Posted at 2019-06-25

はじめまして、普段はPMをやっているtatsukenと申します。はじめまして
研修の一環でvue.js、expressを書くことがあったので、そのことを中心にまとめていきたいと思います

はじめに

ExpressでMysqlを使用する際Mysql2をしようすることがあると思いますが、関連するテーブルが多くなれば多くなるほどqueryの中にqueryを書くと言うようにネストが深くなっていき、どんどん可読性が下がってしまいます。
そのような問題を解決するためにMysql2/promiseが用意されています。

Mysql2/promise使わずコールバックを使用する場合

sample.js
const express = require('express')
const mysql = require('mysql2');
const app = express()
const db_setting = {
    host: 'db',
    user: 'hoge',
    password: 'hoge',
    database: 'hoge',
}
app.get('/', (req, res) => {
    const connection = mysql.createConnection(db_setting)
    connection.connect()
    connection.beginTransaction(function (err) {
        if (err) {
            connection.rollback(function () {
                throw err;
            });
            res.json({
                status: "error",
                error: "fail to uplord data"
            })
            connection.end()
            return
        }
        const hoge1 = {
            name: "hoge1",
        }
        connection.query('insert into table_name set ?', hoge1, (err, rows) => {
            if (err) {
                connection.rollback(function () {
                    throw err;
                });
                res.json({
                    status: "error",
                    error: "fail to uplord data"
                })
                connection.end()
            } else {
                const hoge2 = {
                    name: "hoge2"
                    insertId: rows.insertId,
                }
                connection.query('insert into table_name set ?', hoge2, (err, rows,) => {
                    if (err) {
                        connection.rollback(function () {
                            throw err;
                        });
                        res.json({
                            status: "error",
                            error: "fail to uplord data"
                        })
                        connection.end()
                    } else {
                        connection.commit(function (err) {
                            if (err) {
                                connection.rollback(function () {
                                    throw err;
                                });
                                connection.end()
                                return
                            }
                            res.json({
                                status: "success",
                                id: rows.insertId
                            })
                            connection.end()
                        });
                    }
                })
            }
        })
    })
});

ここではコールバックを使用しているのでネストの深さやコード量のせいで可読性が下がっています。

解決策

Mysql2/promiseを使いasync/awaitで書く

sample.js
const express = require('express');
const app = express.Router();
const mysql = require('mysql2/promise');
app.get('/', (req, res) => {
    const hoge1 = {
        name: "hoge1",
    }
    let connection
    try {
        connection = await mysql.createConnection(db_setting)
        await connection.beginTransaction();
        const [row1] = await connection.query('insert into table_name set ?', hoge1);
        const hoge2 = {
            name: "hoge2"
            insertId: row1.insertId,
        }
        const [row2] = await connection.query('insert into table_name set ?', hoge2);
        await connection.commit();
        res.json({
            status: "success",
            id: row2.insertId
        });
    } catch (err) {
        await connection.rollback();
        res.json({
            status: "error",
            error: "fail to uplord data"
        })
    } finally {
        connection.end()
        return
    }

});

このようにasync awaitを使うことで大幅にコード量を減らすことができ、ネストが深くなるという問題も解決する事が出来ました。
##注意点

  • mysql2をインポートするだけではasync/awaitを使うことは出来ません。
  • mysql2/promiseを使う際はasync/awaitを使ってください。
  • mysql2/promiseを使うとコールバックは認識されなくなります。

最後に

mysql2/promiseを使うと非常に簡潔にコードを書くことが出来ます。機会があればぜひ使って見てください。
なにか間違いなどあれば、教えていただけると幸いです。

24
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?