Использовать глобальную переменную для обмена db между модулем
Я работаю над приложением nodejs/mongodb, используя модуль "mongodb". Приложение запускается с помощью
node main.js
В main.js я подключаюсь к db и сохраняю соединение в глобальной переменной db. "db" затем используется во внутренних методах "сервера". Я хочу избежать "db" как глобальной переменной, но не нашел правильного пути.
Мой текущий main.js:
var server = require('./lib/server');
var MongoClient = require('mongodb').MongoClient;
var Server = require('mongodb').Server;
var mongoClient = new MongoClient(new Server(HOST, PORT));
db = null;
// Database connection
mongoClient.open(function(err, mongoClient) {
if(!err){
// Database selection
db = mongoClient.db(DB);
// Launch web server
server.start(); // usage of 'db' in this part
} else {
console.log(err.message);
process.exit(1);
}
});
Любая идея более чистого пути?
UPDATE
Наконец, я создал модуль в connection.js:
var config = require('../config/config');
var url = 'mongodb://' + config.db.host + ':' + config.db.port + '/' + config.db.name;
var MongoClient = require('mongodb').MongoClient;
var db = null;
module.exports = function(cb){
if(db){
cb(db);
return;
}
MongoClient.connect(url, function(err, conn) {
if(err){
console.log(err.message);
throw new Error(err);
} else {
db = conn;
cb(db);
}
});
}
Каждый раз, когда мне нужно получить соединение, я вызываю:
var connection = require('./connection');
connection(function(db){
// doing some stuff with the db
});
Это работает очень хорошо.
Любая потенциальная ошибка при таком подходе?
Ответы
Ответ 1
Я обычно включаю файл утилиты проекта, который содержит несколько таких вещей, просто чтобы сделать его легким. Он функционирует как псевдо-глобальный, но без многих обычных проблем, связанных с глобальными.
Например,
projectUtils.js
module.exports = {
initialize: function(next){
// initialization actions, there can be many of these
this.initializeDB(next);
},
initializeDb: function(next){
mongoClient.open(function(err, mongoClient) {
if(err) return next(err);
module.exports.db = mongoClient.db(DB);
next();
});
}
}
app.js
var projectUtils = require('projectUtils');
// (snip)
projectUtils.initialize(function(err) {
if(err) throw err; // bad DB initialization
// After this point and inside any of your routes,
// projectUtils.db is available for use.
app.listen(port);
}
Используя асинхронную функцию initialize(), вы можете быть уверены, что все соединения с базой данных, файлы ввода/вывода и т.д. выполняются до запуска сервера.
Ответ 2
Вы можете создать оболочку как поставщика и поместить ее в provider.js, например.
Provider = function (db_name, host, port, username, password) {
var that = this;
var conn = generate_url(db_name, host, port, username, password); // you need to implement your version of generate_url()
MongoClient.connect(conn, function (err, db) {
if (err) {
throw err;
}
that.db = db;
});
};
//add the data access functions
Provider.prototype.getCollection = function (collectionName, callback) {
this.db.collection(collectionName, collectionOptions, callback);
};
exports.Provider = Provider;
Вот как вы пользуетесь провайдером:
var db = new Provider(db_name, host, port, username, password);
db.getCollection('collection name', callback);