【问题标题】:Structure of Express/Mongoose appExpress/Mongoose 应用程序的结构
【发布时间】:2014-05-22 21:49:23
【问题描述】:

我应该如何构建我的 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 );    
            });
        };
    };
}

模块/用户/路由.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: Cannot call method 'userlist' of undefined (routes.js)。

【问题讨论】:

    标签: javascript node.js express mongoose


    【解决方案1】:

    有或多或少两个轴来组织您的代码。根据模块的层功能(数据库、模型、外部接口)或它们作用的功能/上下文(用户、订单)组织代码。大多数 (MVC) 应用程序使用功能性组织架构,这种架构更易于处理,但不会揭示应用程序的目的或意图。

    除了组织代码功能层外,还应尽可能解耦。

    代码中的功能层是

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

    上面的代码库似乎使用了功能组织架构,这很好。使用modules 目录对我来说真的没有意义,而且似乎是多余的。所以我们有一个类似这样的模式

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

    现在让我们打破一些依赖关系...

    schema.js

    代码的架构/模型部分不应依赖于代表您应用的接口的应用。这个版本的schema.js 导出模型,不需要将 express 应用或 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;
    

    此代码省略了获取一个用户和创建新用户的实现,因为这些实现应该与userlist 非常相似。 userlist 路由现在只负责在 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路径下的mounter。

    【讨论】:

      【解决方案2】:

      我写了一个模块orm-model,它可以帮助你在你的nodejs应用中构建模型。

      【讨论】:

        【解决方案3】:

        我最近浏览了一个生成 this sample app 的教程,它具有我见过的最好的结构之一。在 /server/models/ 下查看 Mongoose 是如何设置的。

        【讨论】:

          【解决方案4】:

          查看我的 express_code_structure 示例存储库,了解我对模块文件系统组织的建议。

          但是,您上面的代码示例是主要的 MVC 违规行为。不要将 app 实例传递给您的模型。不要让您的模型知道任何req 对象或HTTP 服务。模型:数据结构、完整性、持久性、业务逻辑,仅此而已。路由应该在与模型完全分开的 .js 文件中定义。

          【讨论】:

            【解决方案5】:

            在您的应用程序结构中,您将数据库逻辑与快速路由处理混合在一起,并将快速应用程序变量传递给模型。我会避免将这两者混合在一起,你也可以看看这个结构https://gist.github.com/fwielstra/1025038

            【讨论】:

              猜你喜欢
              • 2023-03-05
              • 1970-01-01
              • 2015-10-21
              • 1970-01-01
              • 2015-12-08
              • 1970-01-01
              • 2017-05-22
              • 2018-06-11
              • 2017-11-19
              相关资源
              最近更新 更多