6

I need to switch the database in loopback datasource based on the request origin

eg. If i make a request from xyz.domain.com I need to select xyz database for the datasource (we are using wildcard subdomain on frontend so there will be multiple such subdomains).

I tried building middleware which extracts the subdomain from every request origin and sets the database for the datasource. Now the problem is after few simultaneous requests, loopback server breaks with "too many connections" error (may be because it's creating new connection thread on every request)

(I am using my-sql connector for datasource )

Following is my middleware code

'use strict';

const DataSource = require('loopback-datasource-juggler').DataSource;
const app = require('../../server/server.js');
const getSubdomain = require('../middlewares/getSubdomain.js');

module.exports = function() {
  return function datasourceSelector(req, res, next) {
    if (req.path !== '/api/check-realm') {
      let subdomain = getSubdomain(req); // this will get me subdomain from request origin

      let dataSource = new DataSource({
        'host': 'localhost',
        'port': 3306,
        'database': subdomain ? subdomain[1] || 'default' : 'default',
        'user': 'user',
        'password': 'user',
        'name': 'mysqlDS',
        'connector': 'mysql'
      }); // This creates new datasource on every request with appropriate database

      let models = app.models();

      models.forEach(function(model) {
        if (model.modelName !== 'Email') {
          model.attachTo(dataSource);
        }
      }); // here I am attaching all models to the newly created datasource.

      app.dataSource("mysqlDS", dataSource);

    }
    next();
  };
};

Other approaches to achieve this can also be helpful.

1 Answers1

0

app.datasources contains all datasources you define in the application.

For example :

//datasources.json

{
  "memo": {
    "name": "memo",
    "connector": "memory"
  },
  "admin": {
    "host": "localhost",
    "port": 27017,
    "url": "",
    "database": "test_db",
    "password": "",
    "name": "admin",
    "user": "",
    "connector": "mongodb"
  }

Then in your code check for subdomain and :

...
if (subdomain === 'admin'){
   models.forEach(function(model) {
        if (model.modelName !== 'Email') {
          model.attachTo(app.datasources.admin);
        }
      });
}
...
Ebrahim Pasbani
  • 9,168
  • 2
  • 23
  • 30