Loading Express Route Handlers Using Naming Conventions
For a little project I’ve been working on, I wanted to load nodejs modules into an express router automagically, using naming conventions by just having folders in a predefined location.
Given this structure:
MyProject/
Apps/
App1/
index.js
App2
index.js
App3
index.js
I wanted to be able to do the equivalent of:
const express = require('express');
var server = express();
router.use('/App1', require('Apps/App1'));
router.use('/App2', require('Apps/App2'));
router.use('/App3', require('Apps/App3'));
Only in a more elegant way.
Why?
This project is a loose collection of modules all served from the same base web app. For example, a GET
request to https://server.com/App1/foo
would be served by a handler attached to the /foo
route in App1/index.js
.
Why? simply organization. A new module (in my sense, not in nodejs’ one) is simply a folder with a collection of paths.
The main (root for all routes)
My base express app is pretty straight forward:
const express = require('express');
var loader = require("./Apps");
var server = express();
server.set('view engine', 'ejs');
var apps = loader.mount(server);
server.listen(server.get('port'), function() {
console.log('Node app is running on port', server.get('port'));
});
And it never changes.
The Loader
All the magic happens in loader.mount(server)
. server
is just an express
instance. At the root of the Apps
folder, I have a little index.js
file with the following code:
var normalizedPath = require("path").join(__dirname);
exports.mount = function(router){
require("fs")
.readdirSync(normalizedPath, { withFileTypes: true })
.forEach((file) => {
if(file.isDirectory()){
var app = require(normalizedPath + "/" + file.name);
router.use('/' + file.name, app);
}
});
};
A “module”
Each folder under Apps
has to have a single index.js
file that follows this structure:
const express = require('express');
const server = express.Router();
module.exports = server;
server.get('/foo', (req, res, next) => {
res.send("hello from foo");
});
Et voilá!
Now all I need to do is create a folder, drop an index.js
file with the structure and worry about the routes. Everything else just works. And all is neatly contained in each folder.
I’m not sure if there are more nodejs kosher ways of achieving the same, but this works for me! If you have other ideas, let me know.