NodeJS+ES7+Express+MySQL打造API server最佳起手式

以往因為javascript的許多殘缺設計,使得我轉身投靠iced-coffeescript(進階版coffeescript)。老實說我用的很開心,在ES5年代,當眾多碼農在callback hall裡苦苦掙扎之時,我已經愉快地使用iced-coffeescript的async/await,輕鬆解決callback hell跟ES6的Promise.all功能。

但隨著時代的演進,javascript語言本身也進化到了ES7,源自coffeescript的胖箭頭跟async也被寫進標準了,加上我受到一些啟發,我想是時候重新擁抱JS,並且好好整理一番我常用的NodeJS+Express+ES7+MySQL起手架。

首先,如果要使用async,NodeJS必須升級到7.0以上,過程一點都不可怕,到官網下載安裝檔然後下一步、下一步、下一步就完成了。

此外,我還是不打算用ORM,因為只要稍微複雜一點的query,SQL還是完勝ORM

把node-mysql改成async/await

原本node-mysql的最佳實踐是用創造一個連線池(pool),把connection的生命週期交給pool去管理/回收,標準用法如下


pool.query('SELECT * FROM User WHERE id=?',[1],(err,result) => {
    if(err) return errorHandler(res,err);
    ...
});

由於async是建構在promise之上,而node-mysql官方似乎沒有提供promise實作,所以我們必須自己包:

// db.js
const db = {
    query (query,params) {
        return new Promise(resolve, reject) {
            pool.query(query,params,(err, result) => {
                if(err) reject(err);
                else resolve(result);
            });
        }
    }
}
export default db;

正由於promise會throw exception,使用時也必須用try catch包住

router.get('/user/:id', async (req,res) => {
    try {
        const user = await db.query('SELECT * FROM User WHERE id=?',[req.params.id])
        const notebook = await db.query('...', otherParams)
    }
    catch (e) {
        return errorHandler(res,err)
    }
});

如果你覺得每次都要try catch太瑣碎,這裡有解決方案A、解決方案B、解決方案C,注意的是,當你有多個query時,用try-catch還是比較省心。

require進化成import

很不幸地,NodeJS 7.0還是不支援import,必須用babel轉譯,而且整個app啟動時必須先require('babel-register'),最佳實踐如下

  1. 修改package.json,然後npm install
"scripts": {
    //假設用node-dev
    "dev": "node-dev --use_strict ./bin/index"
  },
"devDependencies": {
    "MD5": "~1.2.0",
    "babel-cli": "^6.24.1",
    "babel-preset-es2015-node4": "^2.1.0",
    "babel-preset-stage-3": "^6.5.0",
    "babel-register": "^6.6.5",
    ...
}
  1. 新增.babelrc
{
      "presets": ["es2015-node4", "stage-3"]
}
  1. 新增./bin/index.js
require('babel-register');
require('../app.js');
  1. npm run dev
整理router

未完待續

你可能感兴趣的:(NodeJS+ES7+Express+MySQL打造API server最佳起手式)