2012-06-03

[Express] リクエストハンドラの引数 next の使い方について

Node.js の Web Application Framework の一つである Express において、リクエストハンドラ第三引数の next の使い方について調べてみました。結局のところこれは一体何なのかというと、next の中身は次にリクエストを処理するべき関数を呼び出してくれる関数オブジェクトです。物好きな人用の説明なら、req, res の状態を持って次のリクエストハンドラに goto する continuation のイメージです。

実際にどのように使うかと言うと、何らかの理由でレスポンスを返さない場合に next() という感じで関数呼び出しを行います。引数として、自分のところで対処できないエラー (例外) が発生した場合はエラーオブジェクトを渡し、エラーはないけれど自分のところで対処するべきリクエストでない場合は引数なしで呼び出します。

エラーが発生した場合に適切に伝搬させるの例

var express = require('express'),
    app = express();

app.get('/error_sync', function (req, res, next) {
    next(new Error('sync error'));
    // この場合は throw new Error('sync error') でもOK
});

app.get('/error_async', function (req, res, next) {
    setTimeout(function () {
        next(new Error('async error'));
    }, 100);
});

app.listen(3000);

自分のところでは対処しないの例: リクエストのパラメータが3の倍数の場合 aho と返す。

var express = require('express'),
    app = express();

// 例えば http://localhost:3000/say/31 を開くと?

app.get('/say/:num', function (req, res, next) {
    var num = req.param('num');

    if (num % 3 === 0) {
        res.type('txt');
        res.send('aho: ' + num);
    } else {
        next();
    }
});

app.get('/say/:num', function (req, res, next) {
    var num = req.param('num');

    res.type('txt');
    res.send('not aho: ' + num);
});

app.listen(3000);

このコードを動作させるためには node.js に加えて express が必要なので、本体に同梱の npm コマンドを使って、同じディレクトリで npm install express として express をインストールする必要があります。