I want to create automatic routing in express, currently i can read directory and add route manually from all available files, added route can also be updated if there are changes in route file
delete require.cache[require.resolve(scriptpath)];
var routescript = {};
try {
routescript = require(scriptpath);
} catch (e){
console.log('Express >> Ignoring error route: ' + route + ' ~ >' + scriptpath);
}
var stack_index = app._router.stack_map[route]
var stack = app._router.stack[stack_index];
if (stack) {
app._router.stack[stack_index].handle = routescript;
console.log('Replace Route Stack \'' + route + '\'');
} else {
app.use(route, routescript);
var stack_index = app._router.stack_map[route] = (app._router.stack.length-1);
console.log('Add Route Stack \'' + route + '\'');
}
But those are only work only before app listen to port,
How to add / remove new route stack after the app listening to port?
One way i can think is close the server configure/add/remove the route the re listen, but i guess that is a bad practice
After poking around with express code, I found this:
router.get('/', function(req, res) {
res.render('index', {
title: 'Express'
});
console.log("adding route")
addGet('/mypath', function(req, res) {
res.send('hi')
});
});
function addGet(path, callback) {
Router = require('express').router;
// We get a layer sample so we can instatiate one after
layerSample = router.stack[0];
// get constructors
Layer = layerSample.constructor;
Route = layerSample.route.constructor;
// see https://github.com/strongloop/express/blob/4.x/lib/router/index.js#L457
route = new Route(path);
var layer = new Layer(path, {
sensitive: this.caseSensitive,
strict: this.strict,
end: true
}, route.dispatch.bind(route));
layer.route = route;
// And we bind get
route.get(callback)
// And we map it
router.stack.push(layer);
}
So then open your browser at localhost
and then at localhost/mypath
it works!!!
I am so stupid....
Express 4 default is capable to add route even after it listening
So why i can't do it before? because on top of router layer stack, i add error handling layer stack, so any router layer i add after it, won't be reachable by request, because when the request is processed it will caught first by error handler layer.
so the correct method is as the following:
I have to manage what index is the error handler stack layer located in app._router.stack
, in this case it is some layer at the very end of array
Add new route, ex: using app.use("/something", function(req, res, next){ res.send("Lol") })
Remove the error handler layer stacks, and put it at the very end of the router stack array
// in this case, error map is array // contain index location of error handling stack layer var error_handlers = app._router.stack.splice(error_map[0], error_map.length); app._router.stack.push.apply(app._router.stack, error_handlers);
Now you are ready to go.
Seven years later I share the same doubt as DeckyFx.
I need setup express stack on startup, then dynamically load "plugins" that have their own routers.
So after reading the current express documentation and not find any method to handle stack layers, I have integrate my own method based on the different answers read around here
It is simple:
My code:
// static tail layers definition
_tailLayers = ['UnknownRouteHandler','ErrorRouteHandler'];
// delete tail layer with filter
app._router.stack = app._router.stack.filter(layer => !_tailLayers.includes(layer?.name));
// inject new route
app.use('/', MyRouter);
// inject again stack tail
app.use(UnknownRouteHandler);
app.use(ErrorRouteHandler);
It's works!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.