Adding some diversity to the libraries, let's experiment with Mongojs (https://github.com/mafintosh/mongojs), a simple library for MongoDB that aims to be as close as possible to the native client.
./config.js
, to store all the common data and just return a simple object with relevant configurations for each environment. For now let's just make sure we have a URLin a format accepted by Mongojs.module.exports = function(env) { var configs = {}; configs.dbUrl = "localhost/coffee_"+env; return configs; };
app.js
, a central place to initialize and gather dependencies, and it will be passed to our DB, which then returns public methods. Let's see that happening in the following code:'''javascript //.. var config = require('../config')(app.get('env')); var models = require('./models')(config.dbUrl); app.set('models', models); //..
rc/models/index.js
with its main responsibilities being to instantiate the db and expose public methods to other modules so that storage details stay encapsulated, keeping the code clean and decoupled.'''javascript module.exports = function(dbUrl) { var mongojs = require('mongojs'), var db = mongojs(dbUrl); var models = { User: require('./user')(db) }; return models; };
user
, has the ability to create one user. Notice that we are not making any validations in this model to keep things simple. Don't go to production without having the models double-checked.'''javascript module.exports = function (db) { var methods = {}; var User = db.collection('users'), methods.create = function(name,email,cb) { User.insert({ name: name, email: email }, cb) }; return methods; }
user.js
route to make use of our DB:'''javascript module.exports = function(Model) { var methods = {}; methods.create = function(req,res,next) { Model.User.create(req.param('name'), req.param('email'), function(err, user) { if(err) return next(err); res.send(user); }); }
Let's open Robomongo (http://robomongo.org/) to see what user data was created; it's super handy to lookup what data we have in MongoDB no matter what library we use.
Let's open a parenthesis here and talk about the if(err) return next(err);
.command This is a pattern that is used to abstract error handling in a single action that is supposed to be treated in Express further down the stack, via app.use
.
src/routes/errorHandler.js
.catchAll()
method for now. Express will know the type of use for this function because its functionality is 4.''' module.exports = function() { var methods = {}; methods.catchAll = function(err, req, res, next) { console.warn("catchAll ERR:", err); res.status(500).send({ error: err.toString ? err.toString() : err }); } return methods; }; '''
routes/index.js
. error handling should be the very last middleware(s)://.. router.use(errorHandler.catchAll); return router; };