Meteor Server-only Web App connecting to Multiple Databases

I’m building a Meteor Web API using this fine-rest, and one of the features of the Web API is that it must be able to connect any one of several databases based on a Web Request from a Meteor client.

.

I understand it’s now possible to connect to multiple databases from one Server Side Only Meteor application from this SO answer (https://stackoverflow.com/questions/20535755/using-multiple-mongodb-databases-with-meteor-js):

It is now possible to connect to remote/multiple databases:


var database = new MongoInternals.RemoteCollectionDriver("<mongo url>");
MyCollection = new Mongo.Collection("collection_name", { _driver: database });

Yet, does this work, does it work if you have the same collection names in both databases? The databases are basically replicas, of course with different MONGO_URLs and with different data.

.

For example:

(1) A Web Request from a client would come into the Meteor Web API. That request would contain data that specified a database ID=2. I would look up that ID and match it to a database URL. I would connect to that database and pull in the collection name “People” and do processing on that data.

.

(2) Another Web Request from a different client comes into the Meteor Web API. This time with a database ID=4, the Web App looks up the database and connects to another, different, URL, and pulls in the same collection name, “People”, yet this time of course it has different data (because of course it’s a different database).

.

Can this work with the same collection names? If so how would that work? Also, what if I had two requests for two different database come in at the same time?

Here’s a diagram:

1 Like

I opened a SO question on this topic: https://stackoverflow.com/questions/45148450/meteor-server-only-web-app-connecting-to-multiple-databases

Any advice is appriciated.

@serkandurusoy, @awatson1978 please, will you give me your advice on this topic?

1 Like

Have you tried it out yet? Another possibility could be using an npm package like mongoose which supports multiple connections explicitly: https://www.npmjs.com/package/mongoose

1 Like

Hey @aadams replied at https://stackoverflow.com/a/45184015/1064151, and copying over the reply here for completeness:

You should define what a “collection name” is.

So within this code:

const database = new MongoInternals.RemoteCollectionDriver("<mongo url 1>");
const MyCollection = new Mongo.Collection("collection_name", { _driver: database });

const database2 = new MongoInternals.RemoteCollectionDriver("<mongo url 2>");
const MyCollection2 = new Mongo.Collection("collection_name", { _driver: database2 });

From your “meteor app” perspective, MyCollection and MyCollection2 are two different javascript constants and therefore two different “meteor collections”. Based on how javascript works, they cannot be named the same.

But since they connect to two different databases and different databases are completely different things (unless the two mongo url strings are the same), their “database collection” names can be the same. They still are two different collections in two different databases.

From a database perspective, concurrency does not matter either. They can respond to concurrent database calls just fine because they are different databases. But then again, your javascript application code must be able to manage this concurrency and handle its results and exceptions, because javascript is not threaded, but evented.

2 Likes

That answers the main question. Thank you!

.

In terms of the concurrency: If I use modules with classes, and these classes are pulling in data from the database of one client based on a request, THEN another request comes in that uses the same modules and classes, and these classes pull in data from a different database… concurrently…

Are modules and the classes within them singletons on the server side? Meaning will two difference instances of the classes within the modules be created with two different datasets based on the database they call into – if they’re called concurrently?

Singleton and concurrency are different concepts here because singleton is pertinent to your connection to each database being unique (through getting cached by the module system, mind you this is not a true singleton) while concurrency is about how your app would behave given that you will need to update two different databases at the same time.

Since a database operation in node is essentially an async operation (don’t confuse with meteor’s fiber enabled sync-style codeing), you can tap into promsies and async/await for managing multiple async functions and have them behave the way you want them to behave.

2 Likes

UPDATE: I opened an issue on what could be a Meteor bug here: https://github.com/meteor/meteor/issues/8939

UPDATE: According to this post, can use multiple datababases like so:

import { Mongo } from 'meteor/mongo';
import { MongoInternals } from 'meteor/mongo';

const db1 = new MongoInternals.RemoteCollectionDriver('mongodb://localhost:27017/db-1');
const People_1 = new Mongo.Collection("People", { _driver: db1,  _suppressSameNameError: true });

const db2 = new MongoInternals.RemoteCollectionDriver('mongodb://localhost:27017/db-2');
const People_2 = new Mongo.Collection("People", { _driver: db2, _suppressSameNameError: true });
6 Likes

Cool I had not known about this private option, it certainly is an important thing to know for anyone who needs multiple databases! Nice find!

2 Likes

Just a heads-up, there’s now a discussion on how best to proceed with the _suppressSameNameError flag here.

2 Likes