So I'm starting to use Node.js. I saw the video with Ryan Dahl on Nodejs.org and heard he recommended Express-js for websites.
I downloaded the latest version of Express, and began to code. I have a fully fledged static view up on /, but as soon as I try sending parameters, I get errors like this:
Cannot GET /wiki
I tried following the guide on expressjs.com but the way one uses routes has changed in the latest version, which makes the guide unusable.
Guide:
app.get('/users/:id?', function(req, res, next){
var id = req.params.id;
if (id) {
// do something
} else {
next();
}
});
Generated by Express:
app.get('/', routes.index);
My problem arises when I try and add another route.
app.get('/wiki', routes.wiki_show);
I've tried a bunch of approaches, but I keep getting the Cannot GET /wiki
(404) error.
routes/index.js looks like this:
exports.index = function(req, res) {
res.render('index', { title: 'Test', articles: articles, current_article: current_article, sections: sections })
};
The only thing I did there was add some parameters (arrays in the same file) and this i working. But when I copy the contents and change exports.index
to exports.wiki
or exports.wiki_show
I still get the Cannot GET /wiki
error.
Can anyone explain to me what I'm missing here? - Thanks.
So, after I created my question, I got this related list on the right with a similar issue: Organize routes in Node.js.
The answer in that post linked to the Express repo on GitHub and suggests to look at the 'route-separation' example.
This helped me change my code, and I now have it working. - Thanks for your comments.
My implementation ended up looking like this;
I require my routes in the app.js:
var express = require('express')
, site = require('./site')
, wiki = require('./wiki');
And I add my routes like this:
app.get('/', site.index);
app.get('/wiki/:id', wiki.show);
app.get('/wiki/:id/edit', wiki.edit);
I have two files called wiki.js and site.js in the root of my app, containing this:
exports.edit = function(req, res) {
var wiki_entry = req.params.id;
res.render('wiki/edit', {
title: 'Editing Wiki',
wiki: wiki_entry
})
}
The route-map express example matches url paths with objects which in turn matches http verbs with functions. This lays the routing out in a tree, which is concise and easy to read. The apps's entities are also written as objects with the functions as enclosed methods.
var express = require('../../lib/express')
, verbose = process.env.NODE_ENV != 'test'
, app = module.exports = express();
app.map = function(a, route){
route = route || '';
for (var key in a) {
switch (typeof a[key]) {
// { '/path': { ... }}
case 'object':
app.map(a[key], route + key);
break;
// get: function(){ ... }
case 'function':
if (verbose) console.log('%s %s', key, route);
app[key](route, a[key]);
break;
}
}
};
var users = {
list: function(req, res){
res.send('user list');
},
get: function(req, res){
res.send('user ' + req.params.uid);
},
del: function(req, res){
res.send('delete users');
}
};
var pets = {
list: function(req, res){
res.send('user ' + req.params.uid + '\'s pets');
},
del: function(req, res){
res.send('delete ' + req.params.uid + '\'s pet ' + req.params.pid);
}
};
app.map({
'/users': {
get: users.list,
del: users.del,
'/:uid': {
get: users.get,
'/pets': {
get: pets.list,
'/:pid': {
del: pets.del
}
}
}
}
});
app.listen(3000);