node.js & express – global modules & best practices for application structure

I’m building a node.js app that is a REST api using express and mongoose for my mongodb. I’ve got the CRUD endpoints all setup now, but I was just wondering two things.

  1. How do I expand on this way of routes, specifically, how do I share modules between routes. I want each of my routes to go in a new file, but obviously only one database connection as you can see i’ve included mongoose at the top of people.js.
  2. Do I have to write out the schema of the model 3 times in my people.js? The first schema defines the model, then I list all the vars out in the createPerson and updatePerson functions. This feels like how I made php/mysql CRUD back in the day lol. For the update function, I’ve tried writing a loop to loop through “p” to auto detect what fields to update, but to no avail. Any tips or suggestions would be great.

Also, I’d love any opinions on the app as a whole, being new to node, it’s hard to know that the way you are doing something is the most efficient or “best” practice. Thanks!


// Node Modules
var express     = require('express');
    app         = express();
    app.port    = 3000;

// Routes
var people      = require('./routes/people');

var locations   = require('./routes/locations');
var menus       = require('./routes/menus');
var products    = require('./routes/products');

// Node Configure

// Start the server on port 3000


// People
app.get('/people', people.allPeople); // Return all people'/people', people.createPerson); // Create A Person
app.get('/people/:id', people.personById); // Return person by id
app.put('/people/:id', people.updatePerson); // Update a person by id
app.delete('/people/:id', people.deletePerson); // Delete a person by id

console.log('Server started on port ' + app.port);


var mongoose = require("mongoose");

// Schema
var Schema = mongoose.Schema;  
var Person = new Schema({  
    first_name: String,
    last_name: String,
    address: {
        unit: Number,
        address: String,
        zipcode: String,
        city: String,
        region: String,
        country: String
    image: String, 
    job_title: String,
    created_at: { type: Date, default: },
    active_until: { type: Date, default: null },
    hourly_wage: Number,
    store_id: Number, // Inheirit store info
    employee_number: Number

var PersonModel = mongoose.model('Person', Person);  

// Return all people
exports.allPeople = function(req, res){
    return PersonModel.find(function (err, person) {
      if (!err) {
        return res.send(person);
      } else {
        return res.send(err);

// Create A Person
exports.createPerson = function(req, res){
    var person = new PersonModel({
        first_name: req.body.first_name,
        last_name: req.body.last_name,
        address: {
            unit: req.body.address.unit,
            address: req.body.address.address,
            zipcode: req.body.address.zipcode,
            region: req.body.address.region,
        image: req.body.image,
        job_title: req.body.job_title,
        hourly_wage: req.body.hourly_wage,
        store_id: req.body.location,
        employee_number: req.body.employee_number
    }); (err) {
        if (!err) {
            return res.send(person);
        } else {
            return res.send(404, { error: "Person was not created." });

    return res.send(person);

// Return person by id
exports.personById = function (req, res){
  return PersonModel.findById(, function (err, person) {
    if (!err) {
        return res.send(person);
    } else {
        return res.send(404, { error: "That person doesn't exist." });

// Delete a person by id
exports.deletePerson = function (req, res){
  return PersonModel.findById(, function (err, person) {
    return person.remove(function (err) {
      if (!err) {
          return res.send( + " deleted");
      } else {
          return res.send(404, { error: "Person was not deleted." });

// Update a person by id
exports.updatePerson = function(req, res){
    return PersonModel.findById(, function(err, p){        
            return res.send(err)
        } else {
            p.first_name = req.body.first_name;
            p.last_name = req.body.last_name;
            p.address.unit = req.body.address.unit;
            p.address.address = req.body.address.address;
            p.address.zipcode = req.body.address.zipcode;
            p.address.region = req.body.address.region;
            p.image = req.body.image;
            p.job_title = req.body.job_title;
            p.hourly_wage = req.body.hourly_wage;
            p.store_id = req.body.location;
            p.employee_number = req.body.employee_number;

                    return res.send(p);
                } else {
                    return res.send(404, { error: "Person was not updated." });


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I have taken another approach here. Not saying it is the best, but let me explain.

  1. Each schema (and model) is in its own file (module)
  2. Each group of routes for a particular REST resource are in their own file (module)
  3. Each route module just requires the Mongoose model it needs (only 1)
  4. The main file (application entry point) just requires all route modules to register them.
  5. The Mongo connection is in the root file and is passed as parameter to whatever needs it.

I have two subfolders under my app root – routes and schemas.

The benefits of this approach are:

  • You only write the schema once.
  • You do not pollute your main app file with route registrations for 4-5 routes per REST resource (CRUD)
  • You only define the DB connection once

Here is how a particular schema file looks:

File: /schemas/theaterSchema.js

module.exports = function(db) {
        return db.model('Theater', TheaterSchema());

function TheaterSchema () {
        var Schema = require('mongoose').Schema;

        return new Schema({
            title: { type: String, required: true },
            description: { type: String, required: true },
            address: { type: String, required: true },
            latitude: { type: Number, required: false },
            longitude: { type: Number, required: false },
            phone: { type: String, required: false }

Here is how a collection of routes for a particular resource looks:

File: /routes/theaters.js

module.exports = function (app, options) {

    var mongoose = options.mongoose;
    var Schema = options.mongoose.Schema;
    var db = options.db;

    var TheaterModel = require('../schemas/theaterSchema')(db);

    app.get('/api/theaters', function (req, res) {
            var qSkip = req.query.skip;
            var qTake = req.query.take;
            var qSort = req.query.sort;
            var qFilter = req.query.filter;
            return TheaterModel.find().sort(qSort).skip(qSkip).limit(qTake)
            .exec(function (err, theaters) {
                    // more code
    });'/api/theaters', function (req, res) {
      var theater; (err) {
        // more code
      return res.send(theater);

    app.get('/api/theaters/:id', function (req, res) {
      return TheaterModel.findById(, function (err, theater) {
        // more code

    app.put('/api/theaters/:id', function (req, res) {
      return TheaterModel.findById(, function (err, theater) {
        // more code

    app.delete('/api/theaters/:id', function (req, res) {
      return TheaterModel.findById(, function (err, theater) {
        return theater.remove(function (err) {
          // more code

And here is the root application file, which initialized the connection and registers all routes:

File: app.js

var application_root = __dirname,
        express = require('express'),
        path = require('path'),
        mongoose = require('mongoose'),
        http = require('http');

var app = express();

var dbProduction = mongoose.createConnection('mongodb://here_insert_the_mongo_connection_string');

app.configure(function () {
        app.use(express.static(path.join(application_root, "public")));
        app.use('/images/tmb', express.static(path.join(application_root, "images/tmb")));
        app.use('/images/plays', express.static(path.join(application_root, "images/plays")));
        app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));

app.get('/api', function (req, res) {
        res.send('API is running');

var theatersApi = require('./routes/theaters')(app, { 'mongoose': mongoose, 'db': dbProduction });
// more code


Hope this was helpful.

Method 2

I found this StackOverflow post very helpful:

File Structure of Mongoose & NodeJS Project

The trick is to put your schema into models directory. Then, in any route, you can require('../models').whatever.

Also, I generally start the mongoose db connection in app.js, and only start the Express server once the connection is up:

mongoose.connection.on('error', function(err) {
  console.log("Error while connecting to MongoDB:  " + err);
mongoose.connection.on('connected', function(err) {
  console.log('mongoose is now connected');
  // start app here
  http.createServer(app).listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));


Method 3

I’d take a look at this project . It is a great example on how to build a nodejs application in a standard way.

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x