2012-03-14 28 views
5

¿Cuál sería la forma más adecuada de compartir la conexión de base de datos en el siguiente fragmento (la variable db) con mis enrutadores/controladores sin convertir la variable db en global?Compartir objetos y evitar globales en 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); 

Viniendo de un fondo de PHP, llegué a pensar en la inyección de dependencias , pero no tengo ni idea de si eso es apropiado en el nodo.

+0

no veo un problema ??? Ya está disponible dentro de la función interna, en su ejemplo. Si no especifica una función en línea sino que llama a una importada de otro módulo, simplemente dele la función como parámetro, posiblemente poniendo la llamada a esa (externa) fn dentro de una función fn anónima como ya se mostró en su ejemplo. –

+0

Después de su edición: dele la función llamada desde el archivo "require" -d como parámetro (y asegúrese de usar ese parámetro allí, por ejemplo, para establecer un módulo-var global para recordarlo para las otras funciones de ese módulo). O bien, dele como parámetro a cualquier función que necesite acceso DB, lo cual sería una programación más limpia de todos modos (hasta cierto punto, eso es). –

+0

Bueno, perdón por la confusión. Actualicé el código en mi pregunta para contener un ejemplo de mis rutas/configuración del controlador. No hay ningún problema con el manejo de errores, pero todavía estoy bastante confundido de lo que debería hacer para acceder al objeto 'db' desde dentro del controlador' users', en este caso, sin convertir primero 'db' en un global. – Industrial

Respuesta

7

mirada intenta en esta forma:

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

controladores/users.js:

module.exports = function (app, db) { 

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

}; 
+1

Uso este método también. Este es el mejor método que no reemplaza la lógica 'require'. Si hay muchos estados para transmitir, en lugar de pasarlos uno por uno, podría pasar un objeto hash con todos los deps necesarios. – chakrit

+0

¡Me salvaste el día! –

2

Terminé usando la respuesta de Vadim Baryshev y puso un poco más adelante mediante la creación de un módulo State que contenga módulos de uso común juntos, para mantener las cosas ordenadas:

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

controladores/users.js:

module.exports = function (app, state) { 

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

}; 
5

no tengo ninguna experiencia con mongoskin pero Mangosta cuidadosamente elude este problema al devolver una instancia Singleton de Mongoose cada vez que lo requiera.

Lo que le permite crear una conexión una vez (en la aplicación init, por lo general) y simplemente usarlo consultando Modelos cuando lo necesite.

También le permite definir sus modelos una vez como esto:

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

Y luego se utilicen cualquier lugar donde necesite desea:

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

Más información sobre cómo Mangosta funciona así, con código de ejemplo se puede encontrar en this answer here.

a partir de documentos de mongoskin, parece que usted tiene que conectar cada vez que desee utilizarlo, lo que se podría simplificar envolviendo la conexión db en un archivo que puede requerir:

db.js

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

lo utilizan:

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

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

El método anterior, donde db se pasa como argumento a todas las funciones que puede necesitar, conduce a la devolución de llamada sopa y se debe evitar si es pos ible.

0

Según lo sugerido por @Jed Watson, el módulo moongoose usa un patrón singleton (anti?), Que se aplica mediante el mecanismo require/export.Aquí es el bit de código específica:

(como se encuentra aquí: 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; 
Cuestiones relacionadas