Node.js + express routes + mongoose, simple and separated
express simple-express-mongooseThis creates a directory with that name and an app.js with this content:
var express = require('express'); var path = require('path'); var favicon = require('static-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); app.use(favicon()); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/users', users); /// catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); /// error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); module.exports = app;
Let's simplify to leave only the routes:
var express = require('express'); var index = require('./routes'); var guestbook = require('./routes/guestbook'); var app = express(); app.use(express.static('public')); app.use('/', index); app.use('/guestbook', guestbook); app.listen(3000, function () { console.log('Listening on port 3000'); })
Requiring all routes just once
Applications tend to grow and so we would have to require every route in the main entrypoint for express. Instead of that we can require just the routes/index.js
exports.home = require('./home'); exports.guestbook = require('./guestbook');
Now app.js has simplified route requires
var express = require('express'); var routes = require('./routes'); // This will require 'routes/index.js' !! var app = express(); app.use(express.static('public')); app.use('/', routes.home); app.use('/guestbook', routes.guestbook); app.listen(3000, function () { console.log('Listening on port 3000'); })
I've seen samples where all routes are added to express with just one line of code, but it wasn't working here for me.
Adding MongoDB support
Ok, now we want to show guestbook messages from a MongoDB database. As we are using mongoose, we must define a schema for each collection, and so we'll create a guestbook.js file in a models folder. Here we could try the same procedure used for routes. We create a models/index.js
file which connects to MongoDB and exports all mongoose schemas. Here is models/index.js
/** * models/index.js * All models are here to import all of them just with one command * in the main app.js, and by the way we connect to MongoDB * Better to use an external config.. I know. * https://github.com/pello-io/simple-express-mongoose * Pello Altadill - http://pello.info */ var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/blog'); // optionally: //mongoose.set('debug', true); exports.GuestBook = require('./guestbook');
And this is the schema definition for the guestbook collection, mongoose style. MongoDB is a schemaless database but this driver forces you to define a schema.
The routes
Routes are separated, one file for the home request, other file for guestbook requests, and so forth as the app grows. home.js is pretty straightforward: when we receive a get request, just render the index.jade
And this is the route for guestbook.js, with the get and the post. post saves data and then redirects to get case.
app.js, finally
Here you have. There are more modules to load to improve this sample app, but at least routes and models now are kept apart.
You can clone, download(at this point of development), copy-paste this project from git>. Don't forget to get the required node modules to make it work!