Hello, I’m new to using the node.js mongodb driver. In the past I’ve used mongoose
for all mongodb related projects. I took M220JS and had a lot of unanswered questions. What is holding me up now is understanding the connection.
The docs point out how to connect and offer some examples here
But the example seems to be written for a one-off use-case rather than a real world application. For instance the example shows closing the connection after the request but in a real application, you would want to re-use the existing connection and take advantage of the connection pool. With that in mind, I have the following mongo.js
require('dotenv').config();
const { MongoClient } = require('mongodb');
const config = require('../../config/index');
const username = encodeURIComponent(config.mongo_db1.user);
const password = encodeURIComponent(config.mongo_db1.pass);
const dbHost = config.mongo_db1.host;
const authMechanism = 'DEFAULT';
const qString = `retryWrites=true&w=majority&authMechanism=${authMechanism}`;
const uri = `mongodb+srv://${username}:${password}@${dbHost}/?${qString}`;
const mongoOptions = {
poolSize: 100,
wtimeout: 2500,
useNewUrlParser: true,
useUnifiedTopology: true,
};
const client = new MongoClient(uri, mongoOptions);
let _db;
client.on('serverClosed', (event) => {
// eslint-disable-next-line no-console
console.log('received serverClosed');
// eslint-disable-next-line no-console
console.log(JSON.stringify(event, null, 2));
// should i call mongoDBConnection() here if connection lost while app running?
});
const mongoDBConnection = async (app) => {
try {
if (client.isConnected()) {
_db = client.db(config.mongo_db1.dbName);
return client.db(config.mongo_db1.dbName);
}
await client.connect();
if (app) app.use(passport.initialize());
_db = client.db(config.mongo_db1.dbName);
return client.db(config.mongo_db1.dbName);
} catch (error) {
return Promise.reject(error);
}
};
const dbObj = () => _db;
module.exports = {
mongoDBConnection,
dbObj,
};
In my application, I call mongoDBConnection()
in my app.js
and it connects as expected on app startup. When it’s time to make a request to the db, I have 2 options with the above code. The first is to call mongoDBConnection()
again and let the drivers client.isConnected()
tell me if I should reconnect. The code in another file looks something like this:
const db = await mongoDB.mongoDBConnection();
const result = await db.collection('image').find({}).toArray();
console.log('what is result', result);
The second option is a little cleaner to use throughout the app because I can call the .dbObj()
at the top of the file:
const db = mongoDB.dbObj();
const result = await db.collection('image').find({}).toArray();
console.log('what is result', result);
The problem with the cleaner option, is it doesn’t check if there is a connection issue. It uses whatever was assigned to _db
. So if connection was lost, I don’t know what happens. The docs point out some options for handling reconnect here, but it’s only for a single server instance:
|`autoReconnect`|boolean|true|optional Enable autoReconnect for single server instances|
What do we do for reconnection to clusters? All I came up with so far from the docs is to listen for a disconnect
client.on('serverClosed', (event) => {
// eslint-disable-next-line no-console
console.log('received serverClosed');
// eslint-disable-next-line no-console
console.log(JSON.stringify(event, null, 2));
// should i call mongoDBConnection() here if connection lost while app running?
});
I don’t know if calling mongoDBConnection()
in the code above would make any since because I don’t think (not sure) it would update the already imported instance of dbObj()
with the updated instance of the connection. Are there drivers to help test fail scenarios with mongodb?
In a nutshell, my questions are:
- How do you re-use the connection in node.js with the driver? Is what I’m doing appropriate?
- How do you handle re-connect if there is a connection issue with the node.js cluster?
- Are there any tools I can use with node.js and the driver to simulate cluster issues like lost connection, slow response times, etc?