deepkit-framework icon indicating copy to clipboard operation
deepkit-framework copied to clipboard

Is Deepkit's ORM multi-tenancy capable?

Open 205g0 opened this issue 3 years ago • 7 comments

Pretty much the title and in particular with Mongo, where I use db as a namespace for tenants on the fly and without initiating new ORM or driver instances. All tenants share the same schema, so all code is DRY and they are isolated, so cannot access entities from other tenants.

205g0 avatar Jun 28 '21 20:06 205g0

The ORM has no multi-tenancy manager functionality per se, but you can create your own pool layer since the Database instance can be quickly created however you want.

import { Database } from '@deepkit/orm';
import { MongoDatabaseAdapter } from '@deepkit/mongo';

type CustomerId = string;

export class User {}

export class TenancyDatabase {
    protected databases = new Map<string, Database>();

    for(customer: CustomerId): Database<MongoDatabaseAdapter> {
         let database = this.databases.get(customer);
         if (!database) {
             const adapter = new MongoDatabaseAdapter('mongodb://localhost/' + customer);
             const database = new Database(adapter, [User]);
             this.databases.set(customer, database);
         }
        return database;
    }
}

And then use TenancyDatabase in your services/controllers:

import {TenancyDatabase, User} from './database.ts';

class ApiController {
    constructor(protected session: Session, protected db: TenancyDatabase) {
    }

    @http.GET('/users')
    async users() {
        return this.db.for(this.session.customerId).query(User).limit(1000).find();
    }
}

marcj avatar Jun 28 '21 20:06 marcj

Ah I see, so you don't want to have a new db driver instance for each tenant because there might be a lot. That's currently not supported for Mongo out of the box since the db comes from the config passed to the MongoDatabaseAdapter and can only be changed globally, not per query/session.

marcj avatar Jun 28 '21 20:06 marcj

Thanks for the quick response and this is already good when having a small number of tenants. Important is that I do not have to redefine schemas for every tenant which seems to be the case.

BTW, great work and architectural directions you took, just learned from Deepkit today and I like it a lot, have to toy around with it the next days!

205g0 avatar Jun 28 '21 21:06 205g0

when having a small number of tenants

If demand grows, we can build that in natively. Wouldn't be much work, but definitely touches a few places.

Thank you! If you have any issues feel free to join our discord at https://deepkit.io/community.

marcj avatar Jun 28 '21 21:06 marcj

but definitely touches a few places.

What I usually do is just using the request's hostname as db name/keyspace as default and if you do this from day 1 you have a perfectly multi-tenancy system without any extra work. 1 db per project is old think from SQL days, (I mean they could also do it but with all their migrations better not...). Db as keyspaces are super powerful.

If you have any issues feel free to join our discord at

Just tried, Discord said "Invite Invalid".

205g0 avatar Jun 28 '21 21:06 205g0

Yeah, can work perfectly fine if you are consistent. Although Mongo has also some kind of "migrations", for the creation of indices. Not in the form of SQL, but you have to create them per tenant and keep them up to date.

Just tried, Discord said "Invite Invalid".

Oh, indeed, it expired. Thanks for letting me know! Created a new one that doesn't expire and updated the site. Here it is: https://discord.gg/U24mryk7Wq

marcj avatar Jun 28 '21 21:06 marcj

Interesting idea. I am subscribing to this thread for new developments. ;)

Rush avatar Jun 29 '21 02:06 Rush