Spatie Multitenancy Package for Laravel
Published on by Paul Redmond
Multitenancy is a hot topic for web developers that need to support multiple clients with the same codebase, but need to keep data separate either via table prefixes or separate databases.
In the Laravel space, Spatie released a new offering recently with an unopinionated multitenancy package to make apps tenant-aware:
Our newest package, laravel-multitenancy, has been released!https://t.co/q9HzfkNw7w
The philosophy of this package is that it should only provide the bare essentials to enable multitenancyDocs: https://t.co/zspuLyt3KN
Video (demo+source dive): https://t.co/i3QzTezcuY pic.twitter.com/cy2Fk4tIe6
— Freek Van der Herten (@freekmurze) May 20, 2020
According to Freek Van der Herten’s introductory post, the “philosophy of the package is that it should only provide the bare essentials to enable multitenancy.”
This package takes care of a few things related to tenancy for you:
- Tracking which tenant is the current tenant.
- Dynamically change the configuration when changing a tenant.
- Tools to help with creating a new tenant database and running migrations on multiple tenants.
We’ll only touch lightly on the package; the best place to get started is reading the laravel-multitenancy documenation.
Tenant Model
At the core of the package is the Tenant
model, which represents each available tenant. You can work with and access the current tenant with a few handy methods provided by the package:
use Spatie\Multitenancy\Models\Tenant; // Get the current tenant, or null if there is no current tenantTenant::current() // Get the same thing via the containerapp('currentTenant'); // Determine if there is a current tenantTenant::checkCurrent() // Setting a tenant instance as the current tenant$tenant->makeCurrent(); // Forget the current tenantTenant::forgetCurrent();
Finding Tenants
After installing the Spatie multitenancy package, you have a tenants
database table that will include a row for each tenant in the application. Part of the job of Spatie’s package is determining which tenant should be used to serve the current request, typically based on a domain name. Out of the box, the package provides a DomainTenantFinder
class to look up a tenant and set it as the current. However, you can configure a custom finder as long as it extends the abstract TenantFinder
class.
Other considerations you need when finding a current tenant include the NeedsTenant
middleware for setting the current tenant based on the incoming request and the global EnsureValidTenantSession
middleware to prevent users from a given tenant to access other tenants.
Tenant-Aware Console and Queues
Another challenge when implementing multi-tenancy is scoping console commands and queue jobs. By default, all queue jobs are tenant-aware, and you can disable that capability via configuration. Spatie’s package provides a TenantAware
and NotTenantAware
to make specific queue jobs aware of which tenant to run for any custom needs.
Another thing you’ll likely need is the ability to run a console command for each tenant or target a specific tenant. This package has you covered with the tenants:artisan
command:
# Run migrate on each tenantphp artisan tenants:artisan migrate # Run migrate on a specific tenant with argsphp artisan tenants:artisan "migrate --seed" --tenant=123
Learn More
You can learn more about this package, get full installation instructions, and view the source code on GitHub at spatie/laravel-multitenancy.
I’d also recommend reading Freek’s post which goes into more in-depth details and reasons for making this package.