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

はじめまして、普段はPMをやっているtatsukenと申します。はじめまして
研修の一環でvue.js、expressを書くことがあったので、そのことを中心にまとめていきたいと思います
# はじめに
[Express](https://expressjs.com/ja/)でMysqlを使用する際[Mysql2](https://www.npmjs.com/package/mysql2)をしようすることがあると思いますが、関連するテーブルが多くなれば多くなるほどqueryの中にqueryを書くと言うようにネストが深くなっていき、どんどん可読性が下がってしまいます。
そのような問題を解決するために[Mysql2/promise](https://www.npmjs.com/package/mysql2#using-promise-wrapper)が用意されています。

**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`を使うと非常に簡潔にコードを書くことが出来ます。機会があればぜひ使って見てください。
なにか間違いなどあれば、教えていただけると幸いです。