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

后端 未结 3 1438
醉话见心
醉话见心 2020-12-23 12:57

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.

相关标签:
3条回答
  • 2020-12-23 13:09

    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.connect('mongodb://localhost/whateverdb')
    mongoose.connection.on('error', function(err) {
      console.log("Error while connecting to MongoDB:  " + err);
      process.exit();
    });
    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'));
      });
    
    });
    
    0 讨论(0)
  • 2020-12-23 13:16

    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
                });
        });
    
        app.post('/api/theaters', function (req, res) {
          var theater;
    
          theater.save(function (err) {
            // more code
          });
          return res.send(theater);
        });
    
        app.get('/api/theaters/:id', function (req, res) {
          return TheaterModel.findById(req.params.id, function (err, theater) {
            // more code
          });
        });
    
        app.put('/api/theaters/:id', function (req, res) {
          return TheaterModel.findById(req.params.id, function (err, theater) {
            // more code
          });
        });
    
        app.delete('/api/theaters/:id', function (req, res) {
          return TheaterModel.findById(req.params.id, 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.bodyParser());
            app.use(express.methodOverride());
            app.use(app.router);
            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
    
    app.listen(4242);
    

    Hope this was helpful.

    0 讨论(0)
  • 2020-12-23 13:24

    I'd take a look at this project https://github.com/madhums/node-express-mongoose-demo . It is a great example on how to build a nodejs application in a standard way.

    0 讨论(0)
提交回复
热议问题