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.