Wednesday, August 16, 2017

Best practice for multiple organisations on couch

Leave a Comment

So I have a node express app using nano with couchdb as the backend, this is running fine. I'm now looking to learn how I would expand it to multiple organisations.

So for instance, a wildcard DNS record allowing https://customername.myapp.com for each customer. I will then check the req.headers.host in the main database, along with checking session cookies etc in each request.

What I'm struggling to get my head around though, is how the backend will work. I think I understand that the correct method is to use a database for each organisation, and copy the design from a template database.

But if this is correct, I don't understand how this translates to my code using nano. I currently use this:

var dbname = 'customer1'; var nano = require('nano')(config.dbhost); var couch = nano.db.use(dbname); 

and then in my functions:

couch.get(somevalue, function(err, body) {     // do stuff }); 

But that won't work when the database itself is a variable. Should I be looking at moving the query to a lower level, eg nano.get('dbname', query... or something else?

EDIT

Hoping someone can give me an example of how to use middleware to change the database name dependent on the host header. I have this so far:

app.use(function(req,res,next) {     var couch = nano.db.use(req.header.host);     next(); }); 

But I don't understand how to pass the couch object through ('couch' is unknown in the rest of my routing). I have tried passing it back through in the 'next(couch)' but this breaks it...

1 Answers

Answers 1

First of all, I'd recommend to have the application working with a single organization. If you want to have 1 database per organization, it should be fairly easy to add more organizations later.

I would have a master database and a template database. The master database would be a database listing the existing organization in the service with some metadata. This is what NodeJS would query first to know from which database you need to fetch data.

The template database would be used to sync design objects to existing or new organizations. You can technically have old organization with old design and they will still work as the data will be consistent.

In your case, the line you're looking for is this one:

var couch = nano.db.use(dbname); 

When you know which database to query, you'll have to create a new nano object for each dbname you need.

You can know which database to use directly if the databases are named after domain name or project name as long as the information is present in the request headers/session.

Anyhow, it's a really wide question that can be answered in many ways and there is no particularly best way of doing things.

You could technically have all of your organization in one database if that works for you. Splitting database allow you to isolate a bit things and make use of ACL but you could technically make database not only for organization but for more specific things.

For example, I made a painting program that stores projects per database and allow people to cooperatively draw on a canvas. Database ACL allowed me to restrict access to people invited in a project. My NodeJS server was techically used only for WebSockets and the webapp was able to communicate with the couchDB directly without NodeJS.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment