Microservices – Designing Multi-Tenant Microservice Architecture

microservices

We're in the process of migrating a monolithic application to microservice architecture. Due to some regulatory requirements, we have to keep client's data from different countries in separate (country specific) databases. I.e US db for US customers, UK db for UK customers…

The following designs that we are considering are as follows:

Option 1: A multi-tenant application with hibernate multi-tenant support that can be scaled to N number of times dependending on demand (think of kubernetes pods). A single instance of this application will be able to connect to all databases.

Option 2: Deploy 1 microservice instance per country database. With an API gateway in front of them routing traffic

If you were to design this type of system, what would your choices be?

Best Answer

I think option 2 is not a bad one, but may not be needed. Micro services are for letting you deal with the needs of multiple applications.

A big factor here, is if there is any difference between the two schemas, and if there ever will be in the future.

Usually, I think using interfaces for repositories is unnecessary; however, it might be worth the effort in this instance. Repository factories will be important for you.

My issue with option 1 is that it is too specific. You should be able to go from the setup which you described, to two separate instances each pointing to its own DB easily. The application should NOT CARE WHERE IT IS GETTING ITS DATA FROM.

While the schema does not differ for your two different database, you can have one repository easily deal with both, without the application knowing the difference:

public class MyEntityRepository : ISavesMyEntity, IGetsMyEntity
{
    public MyEntityRepository(string connectionString)
    {
       _connectionString = connectionString;
    }
}

public class MyEntitySaverFactory
{
    public ISavesMyEntity GetSaver(User user)
    {
        if (user.IsUK)
            return new MyEntityRepository(Config.Get("UKConnString"));
        if (user.IsUS)
            return new MyEntityRepository(Config.Get("USConnString"));
        throw new NotImplementedException();
    }
}

//USE
ISavesMyEntity saver = factory.GetSaver(currentUser);
saver.Save(myEntityInstance);

If the DB schemas ever become disparate between the US and UK, then you would then split the functionality into two completely different repositories. This would be easy, since all you would have to do is change your factory.

Related Topic