I would like to have opinions/suggestions whether this is a good way to implement/enhance the MVC pattern with Node.js and Express.js
1) I initialize the app normaly, but at this stage I call a function I named routeRegistrar
, as follows:
var
express = require('express'),
routeRegistrar = require('./routeRegistrar'),
var app = express.createServer();
configureApp(app);
routeRegistrar(app); //note this line
app.listen(3000, function(){
console.log("App started");
});
function configureApp(app){
app.configure(function(){
//configuration stuff with app variable
});
}
2) I adopt the convention that every controller will be placed on a directory called Controllers
, and that every controller is constituted by a module that contains one or more actions, pushed to the exports
variable as an object following the above convention:
{ method: 'GET', url: '/example', action: function(req, res){ } }
So this way I can automatize the route registering process, and also keep the method/url close to the code that handles the request (I think its easier to read/maintain). So the code for the routeRegistrar
is the following:
var fs = require('fs');
module.exports = function(app){
fs.readdirSync(__dirname + '/controllers').forEach(function(controllerName){
var controller = require("./controllers/" + controllerName);
for (var actionName in controller) {
var action = controller[actionName];
app[action.method](action.url, action.action);
}
});
}
And simple a indexController would look like this:
exports.index = {
url: "/",
method: "get",
action: function(req, res){
res.render('index');
}
}
IMHO I believe this is a better approach to every time I wanted a new controller/route registered I had to
1- open app.js
2- place another require line at the top
3- write code like app.get('/index', indexController.index);
Please, let me know wheter this is a good way to continue the project, I would like to hear your opinions and suggestions.
EDIT: Based on Tyrsius answer and the lack of another opinions I will use his approach with some modifications:
routeRegistrar.js
var fs = require('fs');
module.exports = function(app){
fs.readdirSync(__dirname + '/controllers').forEach(function(controllerName){
var controller = require("./controllers/" + controllerName);
for (var actionName in controller) {
controller[actionName](app);
}
});
};
indexController.js
module.exports.index = function(app){
app.get("/", function(req, res){
res.send("New approach!");
});
};
This is not a bad solution, but I think making your own syntax for routes will be confusing. Being able to use the same route syntax that Node/Express are used to will help you out in the long run. You won't be unfamiliar with it when you go to a new project, and you will be able to ask for help since you will be using the syntax everyone else does.
I use a similar solution, it looks like this. It will grab every .js file in the /routes
directory at startup, so you can add controllers without needing to change any code.
in app.js
// Routes
require('./routes')(app);
routes/index.js
var fs = require('fs');
module.exports = function(app){
//GET home page
app.get('/', function(req, res){
res.render('index');
});
//Load other controllers/routes
fs.readdirSync(__dirname).forEach(function(file) {
if (file == "index.js") return;
//var name = file.substr(0, file.indexOf('.'));
require(__dirname + '/' + file)(app);
});
};
example route/controller:
module.exports = function(app){
app.post('/login', function(req, res){
//stuff
});
//other actions on this route
};