Multi-tenancy became very popular with cloud solutions and scalable resources. For those, who doesn’t know, what multi-tenancy means, I should start with single-tenant architecture and take it from there.
- Single tenant architecture is when one instance of the software handles just one client (tenant). If there are several clients, there should be several separate instances of that software. There are no shared resources between clients here.
- Multi tenant architecture is when one instance of the software handles several clients (tenants). With such architecture resources are shared between clients. There can be some resource isolation per client, like separate databases, but in general the goal of multi-tenancy is sharing.
The term “software multitenancy” refers to a software architecture in which a single instance of software runs on a server and serves multiple tenants. Systems designed in such manner are often called shared. A tenant is a group of users who share a common access with specific privileges to the software instance. With a multitenant architecture, a software application is designed to provide every tenant a dedicated share of the instance — including its data, configuration, user management, tenant individual functionality and non-functional properties.
There are several benefits of using multi-tenant architecture like lower cost of ownership, easier scaling process, simplified updates and maintenantce but there are also some challenges. Once of the main challenge is configuration. Usually all multi-tenant solutions are designed to be highly configurable so that every tenant can customize the application look and feel and behavior the way they want.
This is where Ajustee comes into play. With Ajustee you can easily customize the look and feel as well as behavior of any application for different tenants keeping all configuration in one place, reviewing differences in settings, if needed.
Ajustee project shares configuration key across all environments. This means that once admin user creates a new configuration key, it’s available for all environments at once. Admin users may specify different values for environments to support different stages of software development live cycle.
But that doesn’t help with tenants since they belong to the same environment. To manage tenant-specific settings we need to use “Overrides” feature. “Overrides” feature is based on incoming http headers of REST API requests. Clients of REST API (or platform specific clients that built on top of REST API) can add any number of additional parameters, “Overrides” feature will scan those parameters every request and replace values, if parameter values match any configured override within the project environment.
Let’s start with creating an override. Within project sub-menu, select “Overrides” menu item, then select an environment and press “Add new override” button.
All we have to specify is override name, in our case it’s “Tenant A values” and it’s filter — “tenantId equals TenantA”. Form allows to create a complicated set of filter rules, we don’t need all that now. Our simple filter means that for every request that has “tenantId” parameter, if the value of that parameter is “TenantA”, the system will replace configuration values to values that belong to the override.
Now, when override is created, we can specify those values. To do that we need to open config key details view and press “Edit” button. In the edit popup, select an environment that has an override, in our case it’s “Testing”, then enable override value and specify something different.
As a summary, we have created a new override, specified a filter value for a specific tenant, then have updated a config key and specified an override value. If you want to review the values for a key, just open a details view. Under details view, you’ll the default value for a key and all available override values within the environment.
Let’s test it using “App Debug” feature. Before testing the override, make sure you have an application created within the same environment.
When we run the test with default settings, meaning there are no extra parameters for a request, we get the default value for a key — “1500”.
But, when we add a header to a request and specify a value we need (“tenantId/TenantA”), we get an overwritten value.
That’s it. With simple steps we can support several tenants for the same project. You can create as many overrides as you need. With several overrides pointed to the same header there should be no conflicts, but if you have a complicated filter with several extra parameters, you may reach a case when it’s OK for both overrides to match the request. Since Ajustee can return only one value per configuration key, it uses “Priority” property of an override to make a decision on what value to apply. They lower the property value, the higher the priority.
An ability to replace values based on extra parameters unblocks a lot of use cases. Multi-tenant support is one of them. But there are many more cases. For example, you can use overrides feature to replace feature flag values for a subset of “beta testers”, just pass a corresponding parameters with a value. You can change system behavior based on operating system, browser, or any other set of parameters, the one you pass with every REST API request.