Tenanti
Multi-tenant Database Schema Manager for Laravel
Tenanti allow you to manage multi-tenant data schema and migration manager for your Laravel application.
Installation
You can either update the composer.json
file and run composer install
or run composer require
directly:
{
"require": {
"orchestra/tenanti": "~3.0"
}
}
composer require "orchestra/tenanti=~3.0"
Configuration
Next add the following service provider in config/app.php
:
<?php
return [
/* ... */
'providers' => [
// ...
Orchestra\Tenanti\TenantiServiceProvider::class,
Orchestra\Tenanti\CommandServiceProvider::class,
],
],
<?php
return [
/* ... */
'aliases' => [
'Tenanti' => Orchestra\Support\Facades\Tenanti::class,
],
];
Publish Configuration
To make it easier to configuration your tenant setup, publish the configuration:
php artisan vendor:publish
Usage for Single Database
Configuration Tenant Driver
Open config/orchestra/tenanti.php
and customise the drivers.
<?php
return [
'drivers' => [
'user' => [
'model' => App\User::class,
'path' => database_path('tenanti/user'),
'shared' => true,
],
],
];
You can customise, or add new driver in the configuration. It is important to note that model
configuration only work with Eloquent
instance.
Using with Orchestra Platform
With Orchestra Platform, the file would be exported to
resources/config/packages/orchestra/tenanti/config.php
Setup migration autoload
For each driver, you should also consider adding the migration path into autoload (if it not already defined). To do this you can edit your composer.json
.
{
"autoload": {
"classmap": [
"database/tenant/users"
]
}
}
Setup Model Observer
Now that we have setup the configuration, let add App\Observers\UserObserver
observer to our User class (such as App\Providers\AppServiceProvider
):
<?php
namespace App\Providers;
use App\User;
use App\Observers\User as UserObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
User::observe(new UserObserver);
}
}
<?php
namespace App\Observers;
use Orchestra\Tenanti\Observer;
class User extends Observer
{
public function getDriverName()
{
return 'user';
}
}
Usage for Multi Database
Instead of using Tenanti with a single database connection, you could also setup a database connection for each tenant.
Configuration Tenant Driver
Open config/orchestra/tenanti.php
and customise the drivers.
<?php
return [
'drivers' => [
'user' => [
'model' => App\User::class,
'path' => database_path('tenanti/user'),
'shared' => false,
],
],
];
By introducing a migration config, you can now setup the migration table name to be tenant_migrations
instead of user_{id}_migrations
.
Database Connection Resolver
For tenanti to automatically resolve your multiple database connection, we need to setup the resolver. You can do this via:
<?php
namespace App\Providers;
use App\User;
use Illuminate\Support\ServiceProvider;
use Orchestra\Support\Facades\Tenanti;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Tenanti::connection('tenants', function (User $entity, array $config) {
$config['database'] = "acme_{$entity->id}";
// refer to config under `database.connections.tenants.*`.
return $config;
});
}
}
Behind the scene, $config
will contain the template database configuration fetch from "database.connections.tenants"
(based on the first parameter tenants
). We can dynamically modify the connection configuration and return the updated configuration for the tenant.
Setting Working Database Connection
You can also use Tenanti to set the default database connection for your application when accessing from a tenant:
<?php
use App\User;
use Orchestra\Support\Facades\Tenanti;
$user = User::find(5);
Tenanti::driver('user')->asDefaultConnection($user, 'tenants_{id}');
Most of the time, this would be use in a Middleware Class when you resolve the tenant ID based on
Illuminate\Http\Request
object.
Console Support
Tenanti include additional command to help you run bulk migration when a new schema is created, the available command resemble the usage available from php artisan migrate
namespace.
Command | Description |
---|---|
php artisan tenanti:install {driver} | Setup migration table on each entry for a given driver. |
php artisan tenanti:make {driver} {name} | Make a new Schema generator for a given driver. |
php artisan tenanti:migrate {driver} | Run migration on each entry for a given driver. |
php artisan tenanti:rollback {driver} | Rollback migration on each entry for a given driver. |
php artisan tenanti:reset {driver} | Reset migration on each entry for a given driver. |
php artisan tenanti:refresh {driver} | Refresh migration (reset and migrate) on each entry for a given driver. |
php artisan tenanti:queue {driver} {action} | Execute any of above action using separate queue to minimize impact on current process. |
Updated less than a minute ago