node.jsmongodbexpressnode-mongodb-native

What is best way to handle global connection of Mongodb in NodeJs


I using Node-Mongo-Native and trying to set a global connection variable, but I am confused between two possible solutions. Can you guys help me out with which one would be the good one? 1. Solution ( which is bad because every request will try to create a new connection.)

var express = require('express');  
var app = express();  
var MongoClient = require('mongodb').MongoClient;  
var assert = require('assert');

// Connection URL
var url = '[connectionString]]';

// start server on port 3000
app.listen(3000, '0.0.0.0', function() {  
  // print a message when the server starts listening
  console.log("server starting");
});

// Use connect method to connect to the server when the page is requested
app.get('/', function(request, response) {  
  MongoClient.connect(url, function(err, db) {
    assert.equal(null, err);
    db.listCollections({}).toArray(function(err, collections) {
        assert.equal(null, err);
        collections.forEach(function(collection) {
            console.log(collection);
        });
        db.close();
    })
    response.send('Connected - see console for a list of available collections');
  });
});
  1. Solution ( to connect at app init and assign the connection string to a global variable). but I believe assigning connection string to a global variable is a not a good idea.

    var mongodb; var url = '[connectionString]'; MongoClient.connect(url, function(err, db) {
    assert.equal(null, err); mongodb=db; } );

I want to create a connection at the app initialization and use throughout the app lifetime.

Can you guys help me out? Thanks.


Solution

  • Create a Connection singleton module to manage the apps database connection.

    MongoClient does not provide a singleton connection pool so you don't want to call MongoClient.connect() repeatedly in your app. A singleton class to wrap the mongo client works for most apps I've seen.

    const MongoClient = require('mongodb').MongoClient
    
    class Connection {
    
        static async open() {
            if (this.db) return this.db
            this.db = await MongoClient.connect(this.url, this.options)
            return this.db
        }
    
    }
    
    Connection.db = null
    Connection.url = 'mongodb://127.0.0.1:27017/test_db'
    Connection.options = {
        bufferMaxEntries:   0,
        reconnectTries:     5000,
        useNewUrlParser:    true,
        useUnifiedTopology: true,
    }
    
    module.exports = { Connection }
    

    Everywhere you require('./Connection'), the Connection.open() method will be available, as will the Connection.db property if it has been initialised.

    const router = require('express').Router()
    const { Connection } = require('../lib/Connection.js')
    
    // This should go in the app/server setup, and waited for.
    Connection.open()
    
    router.get('/files', async (req, res) => {
       try {
         const files = await Connection.db.collection('files').find({})
         res.json({ files })
       }
       catch (error) {
         res.status(500).json({ error })
       }
    })
    
    module.exports = router