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.
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
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.