Jhonathan Asimov
Jhonathan Asimov

Reputation: 57

Share MongoDb connection between node.js applications

My goal is to set up an express based api with node.js using mongodb version 4.0 and node.js driver 3.1.10.
At the current stage my part of the api is basically done but eventually my collegues will merge their progress on to it. So my question is:
How can I share my connection instance of mongodb to acces it across multiple methods?

My current structure is of this type:

Searching on the web resulted that is recommended to keep a connection open so the nodejs driver will mange it for all queries, so what part of the connection I have to expose:

And when and where I have to open the connection and do I have to close it?

I know that some similar questions exists but they are old and refer to mongodb api and javscript implementations that are old too, so with the use of callbacks or awaits how can I achieve this?

Upvotes: 4

Views: 1516

Answers (2)

Hoppo
Hoppo

Reputation: 1170

You don't have to create a module now. Express has a built in feature to share data between routes. There is an object called app.locals. We can attach properties to it and access it from inside our routes. You simply instantiate your mongo connection in your app.js file.

var app = express();

MongoClient.connect('mongodb://localhost:27017/')
.then(client =>{
  const db = client.db('your-db');
  const collection = db.collection('your-collection');
  app.locals.collection = collection;
});
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // view engine setup
app.set('views', path.join(__dirname, 'views'));

This database connection can now be accessed within your routes as below without the need for creating and requiring additional modules.

app.get('/', (req, res) => {
  const collection = req.app.locals.collection;
  collection.find({}).toArray()
  .then(response => res.status(200).json(response))
  .catch(error => console.error(error));
});

This method ensures that you have a database connection open for the duration of your app unless you choose to close it at any time. It's easily accessible with req.app.locals.your-collection and doesn't require additional modules.

Upvotes: 2

radar155
radar155

Reputation: 2220

You have to create a module, that exports the connection object created by the MongoClient.connect method. The problem here is that the method is asynchronous, so you have to handle it. You have multiple choices. One way could be this:

database.js

const MongoClient = require('mongodb').MongoClient
let url = 'mongodb://xxx'
let connection

module.exports = function() {
   return new Promise((resolve, reject) => {
      if (connection)
         resolve(connection)
      MongoClient.connect(url, (err, db) => {
         if (err)
            reject(err)
         connection = db
         resolve(connection) 
      })
   })
}

another module

var getMongoDbConnection = require('./database.js')

getMongoDbConnection()
.then((db) => {
    // your connection object
})
.catch((e) => {
    // handle err
})

// or inside an async method
app.get('/middleware' => async function(req, res, next) => {
    try {
       let db = await getMongoDbConnection()
    } catch (e) {
      // handle
    }
})

Upvotes: 1

Related Questions