javascript – Express / Mongoose应用程序的结构

我应该如何构建我的express / mongoose应用程序,以便我可以使用我的模式,模型,路由以及在命中这些路由时调用的函数?

server.js

// setup
var express = require("express");
var app = express();
var mongoose = require("mongoose");
app.db = mongoose.connect( 'mydb' ) );

// this is the bit I am not sure about
var UserSchema =  require( './modules/users/schema' )( app, mongoose );
var routes = require( './modules/users/routes' )( app, mongoose, UserSchema );

// listen
app.listen( 3000 );

模块/用户/ schema.js

exports = module.exports = function( app, mongoose ) 
{
    var UserSchema = mongoose.Schema(
    {
        username: { type: String, required: true },
        password: { type: String }
    });

    var UserModel = mongoose.model( 'User', UserSchema, 'users' );

    // it looks like this function cannot be accessed
    exports.userlist = function( db )
    {
        return function( req, res ) 
        {
            UserModel.find().limit( 20 ).exec( function( err, users ) 
            {
                if( err ) return console.error( err );
                res.send( users );    
            });
        };
    };
}

模块/用户/ routes.js

function setup( app, mongoose, UserSchema )
{
    var db = mongoose.connection;

    // get all users
    app.get( '/api/v1/users', UserSchema.userlist( db) ); // this function cannot be accessed

    // get one user
    app.get( '/api/v1/users/:id', UserSchema.userone( db ) );

    // add one new user 
    app.post( '/api/v1/users', UserSchema.addone( db ) );
}

// exports
module.exports = setup;

PS:我得到的错误是app.get(‘/ api / v1 / users’,UserSchema.userlist(db));
TypeError:无法调用undefined(routes.js)的方法’userlist’.

解决方法:

有或多或少的两个轴来组织您的代码.根据模块的层功能(数据库,模型,外部接口)或按功能/上下文(用户,订单)组织代码.大多数(MVC)应用程序使用功能组织架构,该架构更易于处理,但不会泄露应用程序的目的或意图.

除了组织代码之外,功能层应该尽可能地分离.

代码中的功能层是

>在应用程序中抽象数据和行为的模型
>构成应用程序外部接口的路由.路线不是应用程序!
>引导代码(server.js),负责启动和连接应用程序的各个部分

上面的代码库似乎使用了功能组织架构,这很好.使用模块目录对我来说并没有多大意义,似乎是多余的.所以我们有一个像这样的架构

|- server.js
|+ users
 |- schema.js
 |- routes.js

现在让我们打破一些依赖…

schema.js

代码的模式/模型部分不应该依赖于代表应用程序接口的应用程序.此版本的schema.js导出模型,不需要将快速应用程序或mongoose实例传递到某种工厂函数:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = Schema({
    username: { type: String, required: true },
    password: { type: String }
});

// Use UserSchema.statics to define static functions
UserSchema.statics.userlist = function(cb) {
    this.find().limit( 20 ).exec( function( err, users ) 
    {
        if( err ) return cb( err );

        cb(null, users);
    });
};

module.exports = mongoose.model( 'User', UserSchema, 'users' );

显然这会错过原始文件中的app.send功能.这将在routes.js文件中完成.您可能会注意到我们不再导出/ api / v1 / users而是/.这使快递应用程序更加灵活,路径自包含.

this post for a article explaining express routers in detail.

var express = require('express');
var router = express.Router();
var users = require('./schema');

// get all users
router.get( '/', function(req, res, next) {
    users.userlist(function(err, users) {
      if (err) { return next(err); }

      res.send(users);
    });
});

// get one user
router.get( '/:id', ...);

// add one new user 
router.post( '/', ...);

module.exports = router;

此代码省略了获取一个用户和创建新用户的实现,因为这些应该与用户列表非常相似.用户列表路由现在只负责在HTTP和您的模型之间进行调解.

最后一部分是server.js中的接线/引导代码:

// setup
var express = require("express");
var app = express();
var mongoose = require("mongoose");

mongoose.connect( 'mydb' ); // Single connection instance does not need to be passed around!

// Mount the router under '/api/v1/users'
app.use('/api/v1/users', require('./users/routes'));

// listen
app.listen( 3000 );

因此,模型/模式代码不依赖于应用程序接口代码,接口具有明确的责任,server.js中的接线代码可以决定在哪个URL路径下安装哪个版本的路由.

上一篇:关于express 连接 mongodb数据库报错


下一篇:javascript – underscore.js .keys和.omit无法按预期工作