Multi-Tenant Design: The Basics
As your software system begins to grow and become a successful, you may find yourself at a place where you will want to monetize your software by allowing other companies to use it. One such design that will come in handy is called the Multi-Tenant design, and it allows you to license your software to other companies, allowing them to use your software system for through some contract. You manage the system, and they are merely an entity within it, a tenant.
At its core, a multi-tenant design is driven by the idea that each tenant contains an identifier, which is then passed through with each request or action. By including this information, the system will know what behavior or data set to pull from.
Traditionally the tenant identifier is GUID that is transferred through HTTP requests as a HTTP header, x-tenant-id. The value is then kept within the thread context, and used to determine the configuration of a request, as well as the data it can access.
Data should either be globally available configuration values, or scoped to the tenant id directly, or by some some other value that is scoped to the tenant id, such as a customer id that is scoped to the tenant id.
We introduce two pieces that you can use to incorporate into your .NET core service, the TenantInterceptor and TenantMessageHandler.
The TenantInterceptor is a middleware that allows us to append the tenant id from the request header to the current HttpContext to be used later.
The next step is that we have to setup our application be able to access the HttpContext, with IHttpContextAccessor extension.
Then we'll implement TenantMessageHandler, which is a component that you can add to the HttpClient request pipeline. In our case we want to be able to send the tenant id along with our original request.
The reason we have to pass the IServiceProvider instead of the accessor, is that the MessageHandler is only instantiated once, and we need our service to be able to rely on the scoped Http request. So we resolve it ourselves.
Once we have those pieces in place, we are able to retrieve the incoming tenant id and forward it along with future requests from our HttpClient.
In the next portion, we will talk about some strategies to structure your data and database depending on your needs!
Source |
Traditionally the tenant identifier is GUID that is transferred through HTTP requests as a HTTP header, x-tenant-id. The value is then kept within the thread context, and used to determine the configuration of a request, as well as the data it can access.
Data should either be globally available configuration values, or scoped to the tenant id directly, or by some some other value that is scoped to the tenant id, such as a customer id that is scoped to the tenant id.
We introduce two pieces that you can use to incorporate into your .NET core service, the TenantInterceptor and TenantMessageHandler.
The TenantInterceptor is a middleware that allows us to append the tenant id from the request header to the current HttpContext to be used later.
The next step is that we have to setup our application be able to access the HttpContext, with IHttpContextAccessor extension.
Then we'll implement TenantMessageHandler, which is a component that you can add to the HttpClient request pipeline. In our case we want to be able to send the tenant id along with our original request.
The reason we have to pass the IServiceProvider instead of the accessor, is that the MessageHandler is only instantiated once, and we need our service to be able to rely on the scoped Http request. So we resolve it ourselves.
Once we have those pieces in place, we are able to retrieve the incoming tenant id and forward it along with future requests from our HttpClient.
In the next portion, we will talk about some strategies to structure your data and database depending on your needs!
Comments
Post a Comment