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

后端 未结 3 1457
醉话见心
醉话见心 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: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.

提交回复
热议问题