Node.js, restify and proper routing

pilotguy picture pilotguy · May 20, 2012 · Viewed 9.8k times · Source

I'm still wrapping my head around Node, but I have a very simple question. I see a lot of node examples where people are declaring their routes and all their logic in a single app.js file (or sometimes splitting them off into subfiles).

My question is basically: is it better to keep all your route declarations in the app or bootstrap a generic route that maps to your file structure. This may seem like a primitive question but my goal is to grasp what's most efficient within node.

I'm currently building an API handler with Restify but I have another app that uses Express (so this question will likely answer both questions).

In my route I can either declare a single route bootstrap like so:

app.all('/api/:package/:controller', function(request, response) {
    var controller = require(
        '../' + request.params.package + '/api/' + request.params.controller
    );
    controller.index(request, response);
    response.end();
});

This basically accepts all calls from the API and targets the proper api controller. Alternatively I can declare each route individually or perhaps even write an loop that goes through each of my controllers and declares them on init. So:

for (var i in packages.controllers) {
    app.all('api/' + package + '/' + controllers[i].name, function(request, response) {
       var controller = require(
           '../' + request.params.package + '/api/' + request.params.controller
       );
       controller.index(request, response);
    }
}

packages.controllers being an array of all possible controllers. Note the above code is not accurate, I have an HMVC folder structure so the code is a bit more complicated than the above. But you get the point.

I'm wondering what the consequences of either are and if it really matters at all?

Thanks!

Answer

gjohnson picture gjohnson · May 20, 2012

I would not recommend a single app.js at all. You will end up with a 5,000+ line file which is a nightmare to maintain.

The largest issue I see with your snippet is that even though require() gets cached, it has to perform a synchronous IO request. It's just a bad habit to get into.

Similar to what Don recommends, I have had the best luck splitting out routes into modules which export a single function which accept an instance of the app. You can think of it as "decorating" the app instance:

// app.js
var app = express.createServer();
app.configure(function(){ //... });

require('./foo')(app);

// foo.js
exports = module.exports = function(app){

    app.get('/whatever', function(req, res){});

};