Multi-Tenancy in Laravel 5.5

For the past few months I have been working on a SaaS which, like most SaaS applications has multi-tenancy at it’s core. In this post, I am going to share code from my application and discuss why I have implemented it the way I have. I have implemented it in such a way that each tenant has their own database, I chose this method because it’ll make it easier to split the databases across multiple servers if the need to scale horizontally ever arises.

Model and Database Configuration

I have 2 databases that will be called for each tenant, the dms_core database which holds the instance information and dms_slug table which will be the tenant specific instance. The tenant and domain models are part of the core, and because of this they both have the following property set

in database.php i’ve modified the configuration to look like the following

This means that I have 2 database connections, mysql_core is the core connection and mysql the default connection for models will be the tenant/instance specific connection that is modified later on.

Migrations

The first table I created was the tenants table, this is the table that is going to keep track of all the SaaS instances.

The second table is the table that is going to store all the domains associated with each instance, the is_root column will be used to redirect non-root domains to the root domain.

Service Provider

The next step is switching out the database, I chose to do this in a service provider because this is where I feel this code should live – it’s specific to the entire application not a just HTTP requests for example.

This code checks to see if the domain is registered to a tenant and then binds the record to the IoC container – this means that I don’t need any additional database queries to fetch the current tenant. One thing I did notice, if null is returned from an IoC container binding the closure is ran every time the binding is resolved, this is why I am returning false. I then change the database name to the slug retrieved from the tenant record.

Middleware

So I’ve bound the tenant to the IoC container, and swapped out the database if a tenant was found matching the domain name. But what do we do in the HTTP layer? Well, I decided to write some middleware to handle this.

If the tenant binding in the IoC container returns false, we can assume that no tenant was found. So lets return a 404, otherwise continue to the next request.

With the way I have implemented this, the maximum number of overhead that is added by the multi-tenancy implementation is 2 database queries which I think is pretty impressive.

I think that covers everything, if anyone has any questions, comments or ideas on how to improve this let me know!

About the Author

Posted by

Categories:

code, development, dms

Add a Response

Your name, email address, and comment are required. We will not publish your email.

The following HTML tags can be used in the comment field: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">