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