In addition to what Jim has said, I would also add another patterns which can make your code cleaner.
Verify route parameters in separate functions
If you use a route with a parameters, say, app.get('/blog/:slug', ...
then you can use app.param
in order to verify if a given slug
exist and perform necessary actions (send 404
or pass your request to another route if there is no that slug
in your database or load a blog post identified by the given slug
) e.g.
function slugParam (req, res, next, slug) {
Post.findBySlug({ slug: slug }, function (err, post) {
if (err) return res.send(500, 'SERVER ERROR');
if (!post) return res.send(404);
res.locals.post = post; // you will be able to access 'post' in your template
next();
})
}
And when you setup you application you have to call app.param e.g.
app.param('slug', slugParam);
With that approach you won't need to check in your request handler if a post identified by a give slug exist - very clean approach.
Split request handler function into middleware functions
You can also split your request handler function into several smaller (cleaner) functions and call them sequentially (actually express will call them for you). Let's say, you build a discussion forum and you have a route like this:
app.get('/forum/:fid/thread/:tid', function(){
// ...
})
You would need to handle forum and thread loading in a single function - very quickly you will see spaghetti code (especially that both operations will be executed asynchronously). In order to fix it you can split that functions into independent ones responsible for one a single functionality e.g. load forum, load thread, etc.
Example:
function loadFormum (req, res, next) {
Forum.load(/* params here */, function (err, forum) {
if (err) return res.send(500);
if (!forum) return res.send(404);
res.locals.forum = forum;
next();
})
}
function loadThread (req, res, next) {
// you can use forum from res.locals.forum here
Forum.findThread(/* params here */, function (err, thread) {
if (err) return res.send(500);
if (!thread) return res.send(404);
res.locals.thread = thread;
next();
})
}
app.get('/forum/:fid/thread/:tid', loadFormum, loadThread, function(){
// cleaner code
})
Or
var forumMiddleware = [loadForum, loadThread]
app.get('/forum/:fid/thread/:tid', forumMiddleware, function(){
// cleaner code
})
With that approach, functions may depend on each other i.e. loadForum
loads a model, which is then used by loadThread
. You may use as many middleware functions as you want to in order to keep your code clear.
I hope that will help.