16 Multi-Tenancy
Multi-Tenancy, as it relates to software development, is when a single instance of an application is used to service multiple clients (tenants) in a way that each tenant’s data is isolated from the other.
To use the Micronaut’s multitenancy capabilities you must have the multitenancy
dependency on your classpath.
implementation("io.micronaut:micronaut-multitenancy")
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-multitenancy</artifactId>
</dependency>
A common requirement for supporting Multi-tenancy is the ability to resolve the current tenant. Micronaut ships with the following built-in TenantResolvers:
name | description |
Resolves the current tenant from an HTTP cookie. See CookieTenantResolver Configuration Properties. | |
Resolves against a fixed tenant id. See FixTenantResolver Configuration Properties. | |
Resolves the current tenant from the request HTTP Header. See FixTenantResolver Configuration Properties. | |
Resolves the current tenant from the authenticated username. See PrincipalTenantResolver Configuration Properties. | |
Resolves the current tenant from the HTTP session. See SessionTenantResolver Configuration Properties. | |
Resolves the tenant id from the subdomain. See SubdomainTenantResolver Configuration Properties. | |
Resolves the tenant id from a system property. See SystemPropertyTenantResolver Configuration Properties. |
Micronaut supports tenant propagation. As an example, take the following scenario:
You want incoming requests to the gateway
microservice to resolve the tenant id via subdomain. However, you want your requests to other internal microservices to include the tenant Id
as an HTTP Header.
Your configuration in the gateway
microservice will look like:
micronaut:
multitenancy:
propagation:
enabled: true
service-id-regex: 'catalogue'
tenantresolver:
subdomain:
enabled: true
tenantwriter:
httpheader:
enabled: true
In the catalogue
microservice the configuration will look like:
micronaut:
multitenancy:
tenantresolver:
httpheader:
enabled: true
To propagate the tenant you will need to write the resolved tenant ID to the outgoing requests.
Currently, Micronaut ships with two built-in implementations for TenantWriter:
name | description |
Writes the current tenant to a Cookie in your outgoing requests. See CookieTenantWriter Configuration Properties. | |
Writes the current tenant to a HTTP Header. See HttpHeaderTenantWriter Configuration Properties. |
16.1 Multi-Tenancy GORM
GORM supports Multi-tenancy and integrates with Micronaut.
To use Micronaut and GORM multitenancy capabilities you must have the multitenancy-gorm
dependency on your classpath. For example in build.gradle
:
build.gradle
compile "io.micronaut.configuration:micronaut-multitenancy-gorm"
GORM is a powerful Groovy-based data access toolkit for the JVM with implementations several data access technologies (Hibernate, Neo4j, MongoDB, GraphQL …).
GORM supports the following different multitenancy modes:
DATABASE
- A separate database with a separate connection pool is used to store each tenants data.SCHEMA
- The same database, but different schemas are used to store each tenants data.DISCRIMINATOR
- The same database is used with a discriminator used to partition and isolate data.
In order to use GORM - Multitenancy you will need to configure the following properties: grails.gorm.multiTenancy.mode
and grails.gorm.multiTenancy.tenantResolverClass
.
Micronaut support for Multi-tenancy integrates with GORM.
The following table contains all of the TenantResolver implementations that ship with `multitenancy-gorm
module and are usable out of the box.
name | description |
Resolves the current tenant from an HTTP cookie. | |
Resolves against a fixed tenant id | |
Resolves the current tenant from the request HTTP Header. | |
Resolves the current tenant from the authenticated username. | |
Resolves the current tenant from the HTTP session. | |
Resolves the tenant id from the subdomain. | |
Resolves the tenant id from a system property. |
You will need to add something like the following snippet to your app configuration:
grails:
gorm:
multiTenancy:
mode: DISCRIMINATOR
tenantResolverClass: 'io.micronaut.multitenancy.gorm.PrincipalTenantResolver'
Please, read GORM Multi-tenancy documentation to learn more.