2

I have a Node.js project dealing with multiple customers. For several reasons, mainly separation of concerns, security, and partial transferability, I have to put every customer's data into a separate Mongo database. All databases store the same object types and thus have the same set of collections with identical structure. I have already found many technical solutions to solve that issue, but my question is more concerned with the best practices handling this situation. A simplified view into my code (omitting the boilerplate code to create a server, module structure, etc.):

const mongoose = require('mongoose');

// Customer codes act as DB names, actually comes from config file or DB
let customers = ['c1', 'c2'];

// keeps all mongoose connections
let conns = {};

// create a connection(pool) for each DB
for (let i in customers) {
    let dbname = customers[i];
    conns[dbname] = mongoose.createConnection(`mongodb://${host}:${port}/${dbname}`);
}

// a simple Schema for blog articles
const ArticleSchema = new mongoose.Schema({
    title: String,
    text: String
});

// keeps all Article models
let Article = {};

// create the identical models for the different DBs
// remember: the dbname is the unique customer's code
for (let dbname in conns) {
    let conn = conns[dbname];
    Article[dbname] = conn.model('Article', ArticleSchema);
}

const app = require('express');
// returns all articles of a certain customer
app.get('/customers/:customerid/articles', function(req, res) {
    // get the customer's code from the URL
    let dbname = req.params.customerid;

    // Query the database
    Article[dbname].find({}, function(err, articles) {
        if (err) return res.status(500).send('DB error');
        res.status(200).send(articles);
    });
});

This code works. Nonetheless, I wonder, if there ist a best practice I am not aware of to handle this kind of requirement. Especially, it feels strange to keep the connections and models in maps and to access the objects with the dbname in square brackets. Please keep in mind that this is an extremely simplified version. In the real version the code is distributed across several modules handling different object types etc.

Note: A simple mongoose.connection.useDb(dbName) to switch to a different database doesn't work since the model has to be registered with respect to the connection, which itself must be bound to a database (as far as I understand it).

Update: Handling every customer with a single node process and setting up a proxy switching to those processes with respect to the customer - as suggested in the question mentioned by Paul - is currently not an option due to the administrative effort necessary to set things up in our current environment. We have to launch the service quickly right now.

4
  • Possible duplicate of Mongoose create connection for multi-tenancy support in node.js Commented Oct 24, 2018 at 20:51
  • @trsft have you found better solution to connect with multiple databases? If yes, please share it. Commented Jun 24, 2019 at 13:07
  • @pelcomppl I didn't find another solution - but didn't search any more, since this works in production since seven months now without any complications. I am still interested in a best practice advise Commented Jun 26, 2019 at 16:17
  • Looking for the same. I am a bit worried about creating multiple connections. For example MongoDB Atlas only allows 100 connections? What do you do? Commented Sep 16, 2019 at 7:39

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.