How to separate the routes and models from app.js using NodeJS and Express

后端 未结 3 636
生来不讨喜
生来不讨喜 2021-01-30 04:13

I\'m creating an app using Node and Express. However, I can see it\'ll soon become difficult to manage all the routes that are placed inside app.js. I have placed

相关标签:
3条回答
  • 2021-01-30 04:53

    Since I don't like repetition, here's what I do:

    // app.js
    //...
    var routes = requireDir('./routes'); // https://www.npmjs.org/package/require-dir
    for (var i in routes) app.use('/', routes[i]);
    //...
    

    And each file in routes is like:

    // routes/someroute.js
    var express  = require('express');
    var router   = express.Router();
    
    router.get('/someroute', function(req, res) {
        res.render('someview', {});
    });
    
    module.exports = router;
    

    This way you can avoid long repetitive lists like this one:

    app.use('/'           , require('./routes/index'));
    app.use('/repetition' , require('./routes/repetition'));
    app.use('/is'         , require('./routes/is'));
    app.use('/so'         , require('./routes/so'));
    app.use('/damn'       , require('./routes/damn'));
    app.use('/boring'     , require('./routes/boring'));
    

    Edit: these long examples assume each route file contains something like the following:

    var router = express.Router();
    router.get('/', function(req, res, next) {
        // ...
        next();
    });
    module.exports = router;
    

    All of them could be mounted to "root", but what for them is "root", is actually a specific path given to app.use, because you can mount routes into specific paths (this also supports things like specifying the path with a regex, Express is quite neat in regards to what you can do with routing).

    0 讨论(0)
  • 2021-01-30 05:02

    As of express 4.x Router is added to support your case.

    A router object is an isolated instance of middleware and routes. You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router.

    Example from expressjs site:

    // routes/calendarRouter.js
    
    var express  = require('express');
    var router = express.Router();
    
    // invoked for any requested passed to this router
    router.use(function(req, res, next) {
      // .. some logic here .. like any other middleware
      next();
    });
    
    // will handle any request that ends in /events
    // depends on where the router is "use()'d"
    router.get('/events', function(req, res, next) {
      // ..
    });
    
    module.exports = router;
    

    Then in app.js:

    // skipping part that sets up app
    
    var calendarRouter = require('./routes/calendarRouter');
    
    // only requests to /calendar/* will be sent to our "router"
    app.use('/calendar', calendarRouter);
    
    // rest of logic
    
    0 讨论(0)
  • 2021-01-30 05:11

    I can suggest you this file structure (according to Modular web applications with Node.js and Express from tjholowaychuk):

    app.js
       modules
          users
             index.js
             model.js
          users-api
             index.js
          static-pages
             index.js
    

    user-api and static-pages export expressjs applications, you can easily mount them in app.js. In users module you can describe some Data Access operations and all methods about manipulating with the User entity (like create, update etc.). Our API module will use all these methods.

    And here is sample code of app.js file (without common express stuff, only mounting routes from different modules):

    var express = require('express');
    var app = express();
    
    // mount all the applications
    app.use('/api/v1', require("user-api"));
    app.use(require("static-pages"));
    
    app.listen(3000);
    

    To use your modules this way you must start your app like this NODE_PATH=modules node app.js (i put this line to package.json file in scripts section).

    Here is sample code of users module:

    index.js

    User = require("./model");
    
    module.exports = {
        get: function(id, callback) {
            User.findOne(id, function(err, user) {
               callback(err, user);
            });
        },
        create: function(data, callback) {
            // do whatever with incoming data here
            data = modifyDataInSomeWay(data);
            var newUser = new User(data);
            newUser.save(function(err, savedUser) {
                // some logic here
                callback(err, savedUser); 
            });
        }
    };
    

    model.js (with Mongoose stuff for example of course!)

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    
    var User = new Schema({
        firstname   : {type: String, required: false},
        lastname    : {type: String, required: false},
        email       : {type: String, required: true}
    });
    
    module.exports = mongoose.model('user', User);
    

    And example of user-api module (here is the main part of the answer about separating routes and models).

    var users = require("users");
    
    var express = require("express");
    var app = module.exports = express(); // we export new express app here!
    
    app.post('/users', function(req, res, next) {
        // try to use high-level calls here
        // if you want something complex just create another special module for this
        users.create(req.body, function(err, user) {
            if(err) return next(err); // do something on error
            res.json(user); // return user json if ok
        });
    });
    

    And example of static-pages. If you are not going to build a kind of REST interface you may simply create several modules that will render pages only.

    var express = require("express");
    var app = module.exports = express(); // we export new express app here again!
    
    app.get('/', function(req, res, next) {
        res.render('index', {user: req.user});
    });
    
    app.get('/about', function(req, res, next) {
        // get data somewhere and put it in the template
        res.render('about', {data: data});
    });
    

    Of course you can do whatever you want with modules. The main idea about expressjs is to use a lot of small apps instead of single one.

    About nodejs modules you can read stackoverflow and docs.

    Hope this helps.

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