2012-03-14 8 views
5

db変数をグローバルにすることなく、ルータ/コントローラで以下のスニペット(db変数)でデータベース接続を共有する最も適切な方法は何ですか? PHPの背景から来るnode.jsでオブジェクトを共有してグローバルを避ける

var mongo = require('mongoskin'), 
db = mongo.db(config.db.adress); 

app.use(function(req, res, next) { 
    db.open(function(err, data) { 
     (err) ? res.send('Internal server error', 500) : next(); 
    }); 
}); 

// Setting up controllers here 
app.post('/users', require('./controllers/users').create); 

、私は約依存性の注入を考えるようになったが、それはノードに適切なだ場合、私は考えています。

+0

私は問題を見ません?あなたの例では、すでに内部関数の中で利用可能です。関数をインラインで指定せず、代わりに別のモジュールからインポートした場合は、その関数にパラメータとして渡します。すでに例に示したようにanonymous fnの中にその(外部)fnを呼び出すこともできます。 –

+0

編集後:パラメータとして "require" -dファイルから呼び出された関数に与えます(実際には、モジュールのグローバル変数を設定してそのモジュールの他の関数を記憶させるなど)。または、DBアクセスを必要とするすべての関数にパラメータとして渡します。これは、とにかく、よりクリーンなプログラミング(ポイントまで)です。 –

+0

まあ、混乱のために申し訳ありません。私は私のルート/コントローラセットアップの例を含むように私の質問のコードを更新しました。エラー処理に問題はありませんが、 'db'オブジェクトを' users'コントローラの内部からアクセスするために、この場合は 'db'をグローバルにする必要はありません。 – Industrial

答えて

7

この方法を見て試してみてください。

app.js:

var mongo = require('mongoskin'), 
db = mongo.db(config.db.adress); 

app.use(function(req, res, next) { 
    db.open(function(err, data) { 
     (err) ? res.send('Internal server error', 500) : next(); 
    }); 
}); 

require('./controllers/users')(app, db); 

コントローラ/ users.js:

module.exports = function (app, db) { 

    app.post('/users', function(req, res, next) { 
     // Your create function 
     // Link to db exists here 
    }); 

}; 
+1

私はこの方法も使います。これは、 'require'ロジックの置き換えにはまだ至っていない最良の方法です。渡す状態がたくさんある場合は、それらを1つずつ渡すのではなく、必要なすべてのdepsでハッシュオブジェクトを渡すことができます。 – chakrit

+0

あなたは私の一日を救った! –

2

私はヴァディムBaryshevの答えを使用して終了し、それを少し取りましたさらに、一般的に使用されるモジュールをまとめて保持するStateモジュールを作成して、物事をきれいに保つために:

state.js:

module.exports = { 
    mongo: require('mongoskin'), 
    db: require('mongoskin').db('myProject-' +process.env.NODE_ENV) 
} 

app.js:

var state = require('./state'); 
require('./controllers/Users')(app, state); 

コントローラ/ users.js:私はmongoskinの経験を持っていないが、マングースはきちんとこれを回避し

module.exports = function (app, state) { 

    app.post('/users', function(req, res, next) { 
     state.db.find({}, function(doc, err) {}); 
    }); 

}; 
5

あなたがそれを必要とするたびにMongooseのSingletonインスタンスを返すことによって問題が発生します。

これにより、接続を1回(通常はアプリのinitで)作成し、必要なときにモデルにクエリを実行するだけで簡単に使用できます。

また、あなたはかつてこのようなあなたのモデルを定義することができます:あなたはこのようにして必要な場所にそれらを使用し、その後

var mongoose = require('mongoose'), 

    TodoSchema = new mongoose.Schema({ 
    title: { 'type': String, 'default': 'empty todo...' }, 
    order: { 'type': Number }, 
    done: { 'type': Boolean, 'default': false } 
    }); 

mongoose.model('Todo', TodoSchema); 

そして:マングースはこのようにどのように機能するかについて

var mongoose = require('mongoose'), 
     Todo = mongoose.model('Todo'); 

詳しい情報は、例コードはthis answer hereにあります。あなたはあなたが必要とすることができ、ファイル内のDB接続をラップすることによって簡素化する可能性があり、あなたがそれを使用するたびに接続するために持っているように見えるmongoskinのドキュメントから

、:

exports.db = require('mongoskin').db('myProject-' + process.env.NODE_ENV); 
db.js

それを使用する:

var db = require('./db'); 

db.open(function(err, data) { 
     (err) ? res.send('Internal server error', 500) : next(); 
    }); 

デシベルは、それを必要とするかもしれないすべての関数の引数として渡されたスープをcallbackにつながり、POSS場合は避けるべきされ、上記の方法、 ible。

0

@Jed Watsonの示唆したように、moongooseモジュールは、require/exportメカニズムによって強制されるシングルトン(anti?)パターンを使用します。ここでは、コードの特定のビットは次のとおりです。

(ここに見られるように:https://github.com/LearnBoost/mongoose/blob/master/lib/index.js

/*! 
* The exports object is an instance of Mongoose. 
* 
* @api public 
*/ 

var mongoose = module.exports = exports = new Mongoose; 
関連する問題