http://expressjs.com/guide/using-middleware.html
expressのmiddlewareに興味がわいたので自作してみます。ですのでまず上記サイトを読むことにしました。
#結論
app.use(function (req, res, next) {})
もしくは
app.use router
か app.use routers
以下は上記サイトを自分なりに解釈した駄文になります。
#Middlewareとは
- request, response, next を受け取るfunction
- どんなコードでもいい
- requestとresponseを変更してよい
- リクエストを終了してもいい
- nextを呼びリクエストを続行してもいい
- リクエストを終了しない場合はnextを必ず呼ぶこと
- オプションでmiddlewareの対象となるパスを指定できる
- アプリケーションレベル、ルーターレベル、エラーハンドリング、ビルドイン、サードパティの5種類がある
#Application level middleware
-
using app.use()
とapp.VERB()
によりexpressインスタンスに紐づけされる。 VERBはgetとか。
全リクエストに紐づけされるmiddlewareの例
// a middleware with no mount path; gets executed for every request to the app
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
紐づけるパスを限定する例
// a middleware mounted on /user/:id; will be executed for any type of HTTP request to /user/:id
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// a route and its handler function (middleware system) which handles GET requests to /user/:id
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
expressで作成したapp.jsのapp.use('/', routes);
の前にとりあえず両方を記述してログを見てみました。
/にアクセスした場合
Time: 1426909974303
/user/3にアクセスした場合
Time: 1426909953812
Request Type: GET
できてますね。app.use('/', routes);
より前に記述しないと/にアクセスしても実行されないので気を付けて。
またパスに対してmiddlewareを複数登録できるようです。'/user/:id'のmiddlewareを以下のように変更します。
app.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
}, function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
/user/3にアクセス
Time: 1426910635722
Request URL: /user/3
Request Type: GET
できましたね。あと別にバラバラに書いても問題ないみたいです。
app.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
});
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
注意点は途中でsendするmiddlewareなどリクエストを終了するmiddlewareがあると以降のmiddlewareは実行されない点です。
app.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
});
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
//実行されない
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
/user/3にアクセス
Time: 1426910635722
Request URL: /user/3
連続して書いた場合、middlewareはシリーズとして扱われます。この利点はシリーズの途中で実行を中止し、次の他のmiddlewareへ移行できる点です。ただしgetなどのVERBメソッドを使用する必要があります。
app.get('/user/:id',
function(req, res, next) {
console.log('One in Middleware Series:');
next();
},
function(req, res, next) {
console.log('Two in Middleware Series::');
next('route');
},
function(req, res, next) {
console.log('Three but never run');
next();
}
);
app.get('/user/:id', function (req, res, next) {
console.log('Another Middleware:');
next();
});
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
実行結果
One in Middleware Series:
Two in Middleware Series::
Another Middleware:
#Router level middleware
express.Router()に紐づけされる以外はアプリケーションレベルと同じようです。
#Error-handling middleware
他と異なり4つの引数を持ちます。
(err, req, res, next)
試しにエラーを強制的に発生させてみます。
app.get('/user/:id', function (req, res, next) {
throw new Error("err")
res.send('USER');
});
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
ブラウザ画面 Something broke!
コンソール
Error: err
at app.use.err.status (/home/ubuntu/workspace/express/demo/app.js:54:9)
at Layer.handle [as handle_request] (/home/ubuntu/workspace/express/demo/node_modules/express
...
できましたね。
詳しくはhttp://expressjs.com/guide/error-handling.html を参照とのことです。
#Built-in middleware
4系からsessionなどの過去に組み込まれていたmiddlewareは全て分離したそうです。ただし静的ファイルを扱う express.static
だけは組み込まれているようです。
#Third-party middleware
Expressは最小構成だから必要ならサードパティのミドルウェアで機能追加してねみたいな話でした。
#まとめ
app.use(function (req, res, next) {})
できればmiddleware作れる。最後まで読む必要なかったな!!
実際つくってみるとRouter返したほうがやりやすいかも。用途によるかな?