2012年8月3日 星期五

一起來用 Courser 吧!管理 Route 的利器!

Standard
跳脫出前端應用之後的 JavaScript 語言,所遭遇的挑戰極大,至今還沒有一個非常好的開發模型和原則,讓人不免抱怨。因為沒有前人可學習,也沒有太多文獻可以參考,所以,為了讓自己能夠更快完全領會 JavaScript 在各種極端環境之下的開發情況,在這一年來,花了相當多的時間投入去做各種不同類型的 Project,從 Web service、Embedded System、System Programming 到各式雲端技術開發,嘗試從中累積更多用 JavaScript 打天下的經驗。唉,慣 C 都不慣 C 了。

不過,做了許多東西後,就會開始有機會重覆開發相同的功能,這時就會希望能重覆利用舊的程式碼,讓同一段程式,不用每次都重寫一次而浪費時間。於是,開始慢慢把之前做過的專案整理,然後整併許多功能,獨立出來變成一個個 Node.js 模組。

Courser 就是這樣被獨立出來的專案,而功能是為 Express Web Framework 提供一個管理 HTTP Routing 的方案。你可以從 github 上找到專案首頁:


Express 範例的傳統做法,是每次增加一個 API 或頁面,就要更動一次主程式檔案(app.js),以管理 HTTP Routing,相當麻煩,尤其當有許多人協同開發時,更多不必要的程式碼衝突便出現了。此外,管理專案中的 Handler 也是件麻煩事,因為我們總不可能將所有的 Handler 寫在同一支檔案裡,必須適當分類分檔,才能便於維護。隨著專案規模越來越大,需求越來越複雜,這便是件苦差事。

這些問題當然有解決方案,Express Source Code 裡的範例,就提供了幾種不同的方法,供開發者參考,只不過,這些方法大部份很簡陋、不通用,多半還是要靠專案開發者自行想辦法,開發一套機制,才能解決需求。因此,之前為了專案的需要,就實作了 Courser 去管理專案下的 HTTP Routing 和所有的 Handler,嘗試讓 routes 不要每次開發出來,都是這麼醜。

Courser 目前已經釋出 v0.0.2,你可以從 NPM 上直接安裝它:
npm install courser


假設你已經會使用 Express Web Framework,你可以直接引入 Courser,並設定 HTTP Routing 的擺放位置:
var express = require('express');
var Courser = require('courser');

var app = express.createServer();

// Loading and Initializing Routes from specific path
var courser = new Courser(app);
courser.addPath(__dirname + '/routes');
courser.init(function() {
    app.listen(3000);
});

Courser 會載入所有指定目路底下的 *.js 檔案,所以在 routes 的目錄下,我們直接建立新檔(如: test.js),然後這樣定義 Routing 和 Handler:
module.exports = {
  '/': index,
  '/hello': hello
};

function index(req, res) {
    res.end('HOME');
};

function hello(req, res, next) {
    res.end('HELLO');
};

你可能不喜歡這樣的型式,喜歡自己針對不同的 HTTP Method 定義不同的 Handler:
module.exports = {
    '/method': {
        get: get,
        post: post
    }
};

function get(req, res) {
    res.end('GET Method');
};

function post(req, res) {
    res.end('POST Method');
};

要使用 Express Web Framework 的 Middleware 機制,從中安插多個 callback function,也可以這樣寫(用 Array 表示):
module.exports = {
    '/middleware': [
        DoSomethingBeforeHandler,
        middleware
    ]
};

function DoSomethingBeforeHandler(req, res, next) {
    console.log('Do Something');
    next();
};

function middleware(req, res) {
    res.render('index', { title: 'Courser Example' });
};

後記

如果日後能加上 auto-reload 和即時抽換 Handler 的功能,就更省事了!