Eliminar asignaciones de ruta en NodeJS Express

Tengo una ruta mapeada como:

app.get('/health/*', function(req, res){ res.send('1'); }); 

¿Cómo puedo eliminar / reasignar esta ruta a un controlador vacío en tiempo de ejecución?

Esto elimina las app.use middleware de app.use y / o app.VERB (get / post). Probado en express@4.9.5

 var routes = app._router.stack; routes.forEach(removeMiddlewares); function removeMiddlewares(route, i, routes) { switch (route.handle.name) { case 'yourMiddlewareFunctionName': case 'yourRouteFunctionName': routes.splice(i, 1); } if (route.route) route.route.stack.forEach(removeMiddlewares); } 

Tenga en cuenta que requiere que las funciones middleware / route tengan nombres :

 app.use(function yourMiddlewareFunctionName(req, res, next) { ... ^ named function }); 

No funcionará si la función es anónima:

 app.get('/path', function(req, res, next) { ... ^ anonymous function, won't work }); 

Express (al menos a partir de 3.0.5) mantiene todas sus rutas en app.routes . De la documentación :

El objeto app.routes contiene todas las rutas definidas asignadas por el verbo HTTP asociado. Este objeto puede usarse para capacidades de introspección, por ejemplo, Express lo usa internamente no solo para el enrutamiento, sino para proporcionar un comportamiento de OPCIONES predeterminado a menos que se use app.options (). Su aplicación o marco también puede eliminar rutas simplemente retirándolas de este objeto.

Sus app.routes deben ser similares a esto:

 { get: [ { path: '/health/*', method: 'get', callbacks: [Object], keys: []}] } 

Por lo tanto, debería poder recorrer la app.routes.get hasta encontrar lo que está buscando y luego eliminarlo.

Es posible eliminar manejadores montados (agregados con app.use) mientras el servidor se está ejecutando, aunque no hay API para hacer esto, por lo que no es recomendable.

 /* 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; } 

Esto es algo que necesito, así que es una lástima que no haya una API adecuada, pero express es simplemente imitar lo que hace la conexión aquí.

 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); 

Y luego cuando vayas a http://...awesome se llamará 🙂

Editar: corrigió el código

Edit2: corregido de nuevo …

Edit3: Quizás una solución más simple es purgar rutas en algún punto y repoblarlas:

 // remove routes delete app._router.map.get; app._router.map.get = []; // repopulate app.get(/path/, function(req,res) { ... }); 

El enfoque anterior requiere que tengas una función nombrada para la ruta. Quería hacer esto también, pero no tenía funciones nombradas para rutas, así que escribí un módulo npm que puede eliminar rutas especificando la ruta de enrutamiento.

Aqui tienes:

https://www.npmjs.com/package/express-remove-route

Puede buscar en el middleware de la ruta Express y posiblemente hacer una redirección.

Como ya se mencionó anteriormente, la nueva API Express no parece ser compatible con esto.

  1. ¿Es realmente necesario eliminar por completo el mapeo? Si todo lo que necesita es dejar de servir una ruta, puede comenzar fácilmente a devolver algún error desde el controlador.

    El único (muy extraño) caso en que esto no sería lo suficientemente bueno es si las rutas dinámicas se agregaron todo el tiempo, y usted quería deshacerse completamente de las antiguas para evitar acumular demasiadas …

  2. Si desea reasignarlo (ya sea para hacer otra cosa, o para asignarlo a algo que siempre devuelve un error), siempre puede agregar otro nivel de direccionamiento indirecto:

     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 }; 

    En mi opinión, esto es más agradable / seguro que manipular algunos elementos internos no documentados en Express.