Tuesday, May 24, 2016

Multitenancy with Spring Boot

For those who are not familiar with the term Multitenancy, let me start answering some questions that may be come to your mind.

What is multitenancy?

It is a software architecture where the same instance of the software serves multiple tenants. You can see a tenant as an organization. For example, if I have a software platform to sell TV's, my tenants could be Samsung, Philips and Sony. The good thing is that with this approach you are sharing resources, and if you work with cloud platforms this could be a good idea. On the other hand, as you know nothing is free, you have to be aware about the security and the isolation of the data and other things. Before you decide if this kind architecture matches with your requirements, you have to study in deep your requirements.

How to implement that?

I will not delve into the details that motivate the choice of a strategy or another. There are three approaches to do that:
  • Separate database per tenant (picture 2).
  • Separate schema per tenant.
  • Share database and schema.

Ok, we are ready to start. In this example, I am going to implement the first option (separata database per tenant). Note that in this example, the tenants will be added dynamically, this means that only adding the configuration of the tenant in the application.yml will be enough for the application be aware of the new tenant.

I remember you, that this example is using Spring Boot and Hibernate.

First of all we have to add in the application.yml the multitenancy configuration we want. In this case, I have two tenants.

Also we have to exclude the default data source configuration that provides Spring Boot.

The next step, is to provide a mechanism to determine, in runtime, which tenant is accessing to the application instance. To do that, Spring provides an interface to implement it.

RequestContextHolderUtil is a class which determines the tenant based on a pattern contained in the Uri of the request.

Now we need a mechanism to select the correct database (DataSource object) based on the current tenant which is accessing to the application. Once you have the tenant id (above step), you only have to extend the class AbstractDataSourceBasedMultiTenantConnectionProviderImpl provided by Spring.

Note that the object Map (attribute of class AbstractDataSourceBasedMultiTenantConnectionProviderImpl) is configured when the Spring context is loaded reading the multitenancy properties from application.yml. This configuration is performed in a class annotated with @Configuration. You can see the code below.


The last step is to implement a Rest controller to access to the data. Note that the Uri of the endpoint contains the 'tenantId' pattern. Of course, there are different ways to do that. For example using domains or subdomains and so on.

Finally, you can find all the implementation in my GitHub profile here


Feel free to contact me for questions or any doubt.

Happy codying

4 comments:

  1. Hi,

    How to manage connection pooling in this kind of sscenario?

    ReplyDelete
  2. Thanks a lot. The issue I have is that JPA is only creating tables in the default datasource's database and does not in all the other tenants. Is this expected and is there a way to make JPA create tables in all tenants?

    ReplyDelete
  3. HOw to get the informtion of all datasources from database

    ReplyDelete