![](/img/trans.png)
[英]MongoDB Query by Date And Sort by Distance (Mongoose + Express App)
[英]Structure of Express/Mongoose app
我应该如何构造我的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 );
});
};
};
}
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:我得到的错误是app.get( '/api/v1/users', UserSchema.userlist( db ) ); TypeError: Cannot call method 'userlist' of undefined
app.get( '/api/v1/users', UserSchema.userlist( db ) ); TypeError: Cannot call method 'userlist' of undefined
(routes.js)。
有大约两个轴来组织代码。 根据模块的层功能(数据库,模型,外部接口)或其作用的功能/上下文(用户,订单)组织代码。 大多数(MVC)应用程序使用功能性组织架构,该架构更易于处理,但不会揭示应用程序的目的或意图。
除了组织代码功能层之外,还应尽可能地分离。
代码中的功能层是
上面的代码库似乎使用了功能组织架构,这很好。 对我来说,使用modules
目录并没有太大意义,似乎是多余的。 所以我们有一个这样的模式
|- server.js
|+ users
|- schema.js
|- routes.js
现在让我们打破一些依赖...
schema.js
代码的架构/模型部分不应依赖于代表应用程序接口的应用程序。 此版本的schema.js
导出模型,不需要将Express应用程序或schema.js
实例传递到某种工厂函数中:
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
了,但/
代替。 这使快递应用程序更加灵活,路线自成一体。
有关详细解释快速路由器的文章,请参见这篇文章 。
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路径下到安装程序的路由的版本。
看看我的express_code_structure示例存储库,以获取有关模块文件系统组织的建议。
但是,您上面的代码示例是主要的MVC违规。 不要将app
实例传递给您的模型。 让您的模型对req
对象或HTTP服务一无所知。 模型:数据结构,完整性,持久性,业务逻辑,仅此而已。 路由应在与模型完全分开的.js文件中定义。
在您的应用程序结构中,您将数据库逻辑与快速路由处理混合在一起,并将快速应用程序变量传递给模型。 我会避免将两者混为一谈,也可以看看这个结构https://gist.github.com/fwielstra/1025038 。
我编写了一个模块orm-model ,可以帮助您在nodejs应用程序中构建模型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.