2014-04-09 2 views
3

익스프레스/몽구스 응용 프로그램을 구조화하여 스키마, 모델, 경로 및 해당 경로에 도달했을 때 호출되는 함수를 사용할 수 있도록하려면 어떻게해야합니까? 내가 오류가 app.get('/api/v1/users', UserSchema.userlist(db)); TypeError: Cannot call method 'userlist' of undefined입니다 : 익스프레스/몽구스 응용 프로그램의 구조

// 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

server.js

(routes.js).

답변

0

응용 프로그램 구조에서 데이터베이스 논리를 고속 경로 처리와 혼합하고 명시 적 응용 프로그램 변수를 모델에 전달했습니다. 나는이 두가지를 함께 섞는 것을 피할 것이고,이 구조를 볼 수도있다. https://gist.github.com/fwielstra/1025038.

2

모듈 파일 시스템 구성에 대한 나의 권장 사항을 보려면 express_code_structure 예제 레포를보십시오.

그러나 위 코드 샘플은 주요 MVC 위반입니다. 모델에 app 인스턴스를 전달하지 마십시오. 모델에 req 개체 또는 HTTP 서비스에 대한 인식이 전혀 없도록하십시오. 모델 : 데이터 구조, 무결성, 지속성, 비즈니스 로직 등. 경로는 모델과 완전히 별개의 .js 파일로 정의되어야합니다.

0

나는 최근에 본 최고의 구조 중 하나를 가지고 this sample app을 생성 한 자습서를 실행했습니다. Mongoose 설정 방법을 보려면/server/models/아래를보십시오.

0

nodejs 앱에서 모델을 구조화하는 데 도움이되는 orm-model 모듈을 작성했습니다.

8

코드를 구성하는 축이 다소 차이가 있습니다. 모듈의 계층 기능 (데이터베이스, 모델, 외부 인터페이스) 또는 사용자가 수행하는 기능/컨텍스트 (사용자, 주문)에 따라 코드를 구성합니다. 대부분의 (MVC) 응용 프로그램은 다루기는 더 쉽지만 응용 프로그램의 목적이나 의도는 밝히지 않는 기능적 조직 스키마를 사용합니다.

조직 코드 외에도 기능 레이어는 가능한 한 분리되어야합니다. 코드에서

기능성 층은

  • 모델입니다 당신의 응용 프로그램 응용 프로그램의 외부 인터페이스를 구성
  • 경로에서 추상 데이터와 행동. 경로는 이 아니며 응용 프로그램입니다! 책임
  • 부트 스트랩 코드 (server.js)를 시작하고 응용 프로그램 코드베이스 위에서 괜찮 기능 조직 스키마를 사용하는 것

의 부분을 연결합니다. modules 디렉토리를 사용하면 실제로 나에게 의미가 없으며 불필요한 것처럼 보입니다.그래서 우리는 응용 프로그램에 의존해서는 안

schema.js

코드의 스키마/모델 부분 ... 어떻게 든 지금이

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

같은 스키마가의 일부 종속성을 중단하자 응용 프로그램의 인터페이스을 나타냅니다. 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을 더 이상 내보내지 않고 / 대신 내보낼 수 있습니다. 이렇게하면 익스프레스 앱의 유연성이 향상되고 경로 자체가 포함됩니다.

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 경로 아래에 어떤 버전의 라우트를 배치할지 결정할 수 있습니다.

관련 문제