Express / Mongoose应用程序的结构 [英] Structure of Express/Mongoose app

查看:94
本文介绍了Express / Mongoose应用程序的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



server.js

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

//这是我不确定的
var UserSchema = require('./modules/users/schema')(app,mongoose);
var routes = require('./modules/users/routes')(app,mongoose,UserSchema);

//听
app.listen(3000);

modules / users / 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');

//看起来这个函数无法访问
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);
});
};
};
}

modules / users / routes.js

 功能设置(app,mongoose,UserSchema)
{
var db = mongoose.connection;

//获取所有用户
app.get('/ api / v1 / users',UserSchema.userlist(db)); //这个函数不能访问

//获取一个用户
app.get('/ api / v1 / users /:id',UserSchema.userone(db));

//添加一个新用户
app.post('/ api / v1 / users',UserSchema.addone(db));
}

// export
module.exports = setup;

PS:我得到的错误是 app.get('/ api / v1 / users',UserSchema.userlist(db));
TypeError:无法调用未定义的方法'userlist'
(routes.js)。

解决方案

p>组织您的代码有两个或更多的轴。根据模块的层次功能(数据库,模型,外部接口)或者按照用户,订单的功能/上下文来组织代码。大多数(MVC)应用程序使用更容易处理的功能组织架构,但不显示应用程序的目的或意图。



除了组织代码功能层应该是



代码中的功能层是




  • 应用程序中的抽象数据和行为

  • 构成应用程序一个外部接口的路由。路由是应用程序!

  • 负责启动和连接应用程序部分的引导代码(server.js)



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

  |  -  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}
});

//使用UserSchema.statics定义静态函数
UserSchema.statics.userlist = function(cb){
this.find()。limit(20).exec(函数(err,users)
{
if(err)return cb(err);

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

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

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



请参阅这篇文章详细解释了快速路由器的详细信息

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

//获取所有用户
router.get('/',function(req,res,next){
users.userlist(function(err,users){$ ($)

res

//获取一个用户
router.get('/:id',...);

//添加一个新用户
router.post('/',...);

module.exports = router;

此代码省略了获取一个用户并创建新用户的实现,因为这些应该与用户列表。 c code code code

$ b

最后一部分是布线/ bootstrapping代码在 server.js

  //设置
var express = require(express);
var app = express();
var mongoose = require(mongoose);

mongoose.connect('mydb'); //单连接实例不需要传递!

//将路由器安装在/ api / v1 / users'
app.use('/ api / v1 / users',require('./ users / routes')) ;

//听
app.listen(3000);

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


How should I go about structuring my express/mongoose application, so that I can use my schemas, models, routes and the functions that get called when those routes are hit?

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 );

modules/users/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 );    
            });
        };
    };
}

modules/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: The error I get is app.get( '/api/v1/users', UserSchema.userlist( db ) ); TypeError: Cannot call method 'userlist' of undefined (routes.js).

解决方案

There are more or less two axes to organize your code. Organize code based on the layer functionality of your modules (database, model, external interface) or by functionality/context they act on (users, orders). Most (MVC) applications use a functional organization schema which is easier to handle but does not reveal the purpose or intend of an application.

Beside organizing code functional layers should be as decoupled as possible.

The functional layers in your code are

  • Models that abstract data and behavior in your application
  • Routes that constitute an external interface of your application. Routes are not the application!
  • Bootstrapping code (server.js) that is responsible to start and connect the parts of your application

The code base above seems to use a functional organization schema, which is fine. The use of a modules directory does not really make sense to me and seems superfluous. So we have a schema somehow like this

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

Now let's break some dependencies...

schema.js

The schema/model part of the code should not depend on the app that represents an interface of your application. This version of schema.js exports a model and does not require an express app or a mongoose instance to be passed into some kind of factory function:

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' );

Obviously this misses the app.send functionality from the original file. This will be done in the routes.js file. You may notice that we do not export /api/v1/users anymore but / instead. This makes the express app more flexible and the route self contained.

See 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;

This code omits implementations for getting one user and creating new users because these should work quite similar to userlist. The userlist route now has a single responsibility to mediate between HTTP and your model.

The last part is the wiring/bootstrapping code in 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 );

As a result the model/schema code does not depend on the application interface code, the interface has a clear responsibility and the wiring code in server.js can decide which version of the routes to mounter under which URL path.

这篇关于Express / Mongoose应用程序的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆