次のようにマップされたルートがあります。
app.get('/health/*', function(req, res){
res.send('1');
});
実行時にこのルートを空のハンドラーに削除/再マップするにはどうすればよいですか?
Express (少なくとも 3.0.5 以降) は、すべてのルートを に保持しapp.routes
ます。ドキュメントから:
app.routes オブジェクトには、関連付けられた HTTP 動詞によってマップされた定義済みのすべてのルートが格納されています。このオブジェクトは、イントロスペクション機能に使用できます。たとえば、Express はルーティングのためだけでなく、 app.options() が使用されない限り、デフォルトの OPTIONS 動作を提供するためにこれを内部的に使用します。アプリケーションまたはフレームワークは、このオブジェクトからルートを削除するだけで、ルートを削除することもできます。
次のapp.routes
ようになります。
{ get:
[ { path: '/health/*',
method: 'get',
callbacks: [Object],
keys: []}]
}
app.routes.get
したがって、探しているものが見つかるまでループしてから削除できるはずです。
上記のアプローチでは、ルートの名前付き関数が必要です。これもやりたかったのですが、ルートの名前付き関数がなかったので、ルーティング パスを指定してルートを削除できる npm モジュールを作成しました。
どうぞ:
サーバーの実行中にマウントされたハンドラー(app.useで追加)を削除することは可能ですが、これを行うためのAPIはないため、お勧めしません。
/* Monkey patch express to support removal of routes */
require('express').HTTPServer.prototype.unmount = function (route) {
for (var i = 0, len = this.stack.length; i < len; ++i) {
if (this.stack[i].route == route) {
this.stack.splice(i, 1);
return true;
};
}
return false;
}
これは私が必要としているものなので、適切なAPIがないのは残念ですが、expressはconnectがここで行うことを模倣しているだけです。
app.get$ = function(route, callback){
var k, new_map;
// delete unwanted routes
for (k in app._router.map.get) {
if (app._router.map.get[k].path + "" === route + "") {
delete app._router.map.get[k];
}
}
// remove undefined elements
new_map = [];
for (k in app._router.map.get) {
if (typeof app._router.map.get[k] !== 'undefined') {
new_map.push(app._router.map.get[k]);
}
}
app._router.map.get = new_map;
// register route
app.get(route, callback);
};
app.get$(/awesome/, fn1);
app.get$(/awesome/, fn2);
そして、あなたが行くときはhttp://...awesome
fn2
呼ばれます:)
編集:コードを修正しました
Edit2:再度修正...
Edit3:たぶんもっと簡単な解決策は、ある時点でルートをパージし、それらを再設定することです:
// remove routes
delete app._router.map.get;
app._router.map.get = [];
// repopulate
app.get(/path/, function(req,res)
{
...
});
Express route ミドルウェアを調べて、リダイレクトを行うことができます。
すでに上で述べたように、新しい Express API はこれをサポートしていないようです。
マッピングを完全に削除する必要は本当にありますか? ルートの提供を停止することだけが必要な場合は、ハンドラーから何らかのエラーを返すことを簡単に開始できます。
これが十分ではない唯一の (非常に奇妙な) ケースは、動的ルートが常に追加されていて、古いものを完全に削除して、蓄積しすぎないようにしたい場合です...
それを再マップしたい場合 (何か他のことをするか、常にエラーを返すものにマップするため)、いつでも別のレベルの間接化を追加できます。
var healthHandler = function(req, res, next) {
// do something
};
app.get('/health/*', function(req, res, next) {
healthHandler(req, res, next);
});
// later somewhere:
healthHandler = function(req, res, next) {
// do something else
};
私の意見では、これは Express で文書化されていない内部を操作するよりも優れた/安全です。
公式の方法はありませんが、 stackでこれを行うことができます。
function DeleteUserRouter(appName){
router.stack = router.stack.filter((route)=>{
if(route.route.path == `/${appName}`){
return false;
}
return true;
});
}
appName はパス名です。
ルーターがexpress.Routerであるrouter.route.stackのメソッドをフィルタリングするか、アプリに対して同じことを行うことができますが、app._router.stackを使用します。
注: 4.0 未満の場合は、app.router.stack を使用します。