Narrative (Node.js week 1-2)
I've been working on Narrative, a story creation site, in node.js; I'm vacillating about turning it into a Facebook game so I'm not putting all of its source into git just yet but I'm putting useful bits of it into open source, such as deformer, my form generation module. Enjoy!
Some takeaways
I am leaning pretty heavy on the express MVC example. I added a minor patch suggestion to the example that cleans up the way the MVC example handles locals.
Its sometimes tough to figure out what is going wrong if you run a MVC action through the browser. Running test scripts and calling controller module actions can give you better insight into what exactly is going on. Here is the test script I wrote for the story creation action:
var story_module = require('./../controllers/story');
var request = {
flash: function(txt){
console.log('flash: ' + txt);
},
params: {id: 0},
body: {
story: {
title: 'foo',
body: 'bar'
}
}
};
var response = {
render: function(data){
console.log('render: rendering ');
console.log(data);
},
redirect: function (path){
console.log('redirect to ' + path);
}
}
user_module.create(request, response);
Permission/Access control
Although you can probably put access control in the controller modules if you want, I find that putting switches on the mvc module definition to be just as practical:
case 'create':
switch(prefix){
case '/storys':
app.post(prefix + '/:id', user_module.if_logged_in, fn);
break;
default:
app.post(prefix + '/:id', fn);
}
This puts an access control gateway function in front of the controller action for stories but allows unfettered access to all other data saving actions.
The fact that all controllers run through the same mapping function means that if you have routes that are particular to a module, you have to put them in the same MVC functions that map general (REST/RoR based) actions to CRUD actions.
/* MODULE SPECIFIC ACTIONS */
/* story */
case 'addchapter':
app.get(prefix + '/:id/:chapterid/addchapter', user_module.if_logged_in, fn);
break;
case 'showchapter':
app.get(prefix + '/:id/:chapterid/showchapter', fn);
break;
and so on... Note that because there is no way to discern a static token like "showchapter" from a named variable slot ":id" in the routes, you have to include slots for :id even for action routes for which "id" is not a relevant value, such as creating new records for which the ID hasn't been created yet.
Clean up your actions early and often
One of the problems (or at least situations) with the controller system is that controller modules' actions are name-mapped to the MVC actions mapper; so any functions that can't be concealed inside the closure of a module are better transported to modules of their own. In short, restrict controller module exports to actions and put everything else somewhere else.

Post new comment