Switch DB dynamically for NodeJS web application - node.js

I am trying to implement a feature which a user can decide on login to which DB to connect. As it is a web-app, running on a server which all the clients approach, how can I implement this feature without changing every client DB?
At our company we are using mongoose as the MongoDB API.
I read all the docs, and didn't notice any functionality for using multiple connections to different DB's on different hosts within the same App at once - without damaging other's client work.
The most valuable thing I have accomplished is to open few connections based on multiple mongoose instances, based on this post:
Mongoose and multiple database in single node.js project
I have created few files for example:
var mongoose = require('mongoose');
mongoose.createConnection('mongodb://10.20.100.71:27017/DB_NAME');
module.exports = exports = mongoose;
And then I required them:
let stageAccess = require('./databsesConnections/stageAccess');
let prodAccess = require('./databsesConnections/prodAccess');
I debugged the files and checked the connections are establishing.
Further more I checked in the mongoose docs and concluded that I can choose which connection is the default connection, as the docs state:
"Mongoose creates a default connection when you call mongoose.connect(). You can access the default connection using mongoose.connection."
So I tried:
mongoose.connection = mongoose.connections[1];
And it works fine.
So the actual question is, what will happen if client 1 approach the app, select to connect dbNum1 and starts to work,
then client 2 approach the app and select to connect to dbNum2?

Related

Express Js - Connecting to MongoDB database on demand

I am working on an application that needs to connect to different MongoDB databases based on the customer that is accessing my application. Each MongoDB database is located on separate servers.
For example, if my application has 3 different customers:
john (mongodb://john:john#server1/john)
tom (mongodb://tom:tom#server2/tom)
harry (mongodb://harry:harry#server3/harry)
when john uses my application, Express.js should connect to mongodb://john:john#server1/john or when harry uses my application, it should connect to mongodb://harry:harry#server3/harry.
I am wondering what an optimized way would be to achieve this. Normally, when we have just one MongoDB database instance, we put the mongoose.connect method inside the app.js and that gets called when the Express.js server starts, but in this case I don't want to connect all three databases at once since that will not be the optimized way.
According to the Mongoose docs, it does support connections to multiple hosts.
const conn1 = mongoose.createConnection('host1', options)
const conn2 = mongoose.createConnection('host2', options)
Let me give you an example (this is Express code) :
// CONNECTION SETTER MIDDLEWARE
app.use(async function (req, res, next) {
// Let's just assume you identified the user earlier with your favourite
// auth method and put their identity in req.user
const userCon = await mongoose.createConnection(`mongodb://${req.user.username}:${req.user.password}#${req.user.host}/${req.user.database}`) // Here you have it!
// Saving the connection in the request so the next
// middlewares/handlers can access it
req.user.connection = userCon
// Thank you, next (middleware/handler)
next()
});
While mongoose.connect() sets the default connection, mongoose.createConnection() only returns a connection.
This is what I would try, and this is Mongoose's recommended way to handle multiple connections. You should note that you can't share Models across different connections, but you can share Schemas.
If you want to just initialize the connection and connect later, the Mongoose docs also provide an example.
// initialize now, connect later
db = mongoose.createConnection();
db.openUri('localhost', 'database', port, [opts]);

Should I worry to close db connection while connecting cloudant db from nodejs using cloudant module?

I am connecting to cloudant using "cloudant" module in nodejs (npm install --save cloudant). Below is the code to initiate the db connection variable and then to use it.
//instantiate a cloudant var with the cloudant url. The url has id, password in it.
cloudant = require('cloudant')(dbCredentials.url);
//set the middleware with the db name
db = cloudant.use(dbCredentials.dbName);
//use the db variable to insert data into the db
function(req){
db.insert({
name:req.name,
age:req.age
},id,function(err,doc){
....
});
};
Should I be worrying about closing the connection after I use db variable? It does not make sense to me since we are not using any connection pool here. To me we are simply instantiating the db variable with the endpoint, credentials and db name. Later we are calling the cloudant resources as ReST APIs. I am slightly confused here and dont think we need to do any close connection (which in fact means nothing but nullifying the cloudant variable). Can please share any comments, whether I am wrong or right? Thanks in advance.
By default, the Cloudant library uses the default Node.js connection pooling so it will respect the server's "Keep-Alive" instruction, but is nothing that you need to worry about. Simply keep making Cloudant library function calls and the library will make HTTP connections when required - reusing existing connections when necessary, creating new ones in other cases.

MongoDB connections on require or by function

I am working on a single pager that writes to different mongodb databases through an API setup with express. To do this I have one file named db.js that is doing all of the work with the mongoose module and then exporting the two connections to my express file called app.js.
When I start running my app file with node, my mongo console shows the two connections being made.
My question is, should I be making the exports structured so that they are functions that only connect to the DB when the functions themselves are called? Is there anything bad about leaving the two connections open and waiting for people to use them?
It is better to have your database connections created on start of the application, and leaving them open. The other way to create connections when an API call is made is extremely inefficient, because the connection load increases wrt number of API calls, and also because the response time of the API increases.
In db.js export your objects.
In your app.js, you can directly require the appropriate connection and start using it
var db = require("../db").first;
db.find({}, function (err, res) {})

Access multiple mongo databases with mongoose

From within a single nodejs app, how can I switch between mongodb instances?
For some context, I'm writing a queue worker with nodejs/zeromq/mongoose.
I have multiple nodejs/mongo apps running on the same server, each with their own mongo database, push jobs to a queue.
My worker app pulls and processes the jobs sequentially.
Depending which app sent the job, it needs to connect to the appropriate mongo database through mongoose. All apps use the same mongoose models, so the same models are already available in my worker app.
I'm having trouble switching connections and I'm afraid listing the details of my attempts/results would muddy up the question here.
It doesn't matter if it's limited to 1 at a time, or if I maintain a collection of connections.
Any insight would be appreciated.
Use createConnection. See the docs Here: http://mongoosejs.com/docs/api.html. I haven't done it myself, but I believe you then just create models attached to each schema
var mongoose = require('mongoose');
var db = mongoose.createConnection(..);
db.model('Venue', new Schema(..));
var Ticket = db.model('Ticket', new Schema(..));
var Venue = db.model('Venue');

Does Mongoose allow for Multiple Database Connections?

I read that in a nodejs application, if we use a mongoose object using
var obj = require('mongoose');
then, wherever we create a new mongoose object (say, in another file), then the same cached copy is used throughout. In that case, how can we connect to multiple database instances of mongoDB in the same nodejs app ?
You can use mongoose.createConnection to connect to a separate database, and then using the connection object that generates, you can define models from that database using connection.model.

Resources