Как использовать оркестровые /tenanti в Laravel 5 для создания приложения с несколькими арендаторами с несколькими базами данных?
Я пытаюсь создать и использовать приложение с помощью Laravel 5. Предполагается, что это архитектура базы данных с несколькими арендаторами, использующая несколько баз данных. Мой работодатель требует этого для целей безопасности.
Я попытался вручную управлять основными переходами БД и миграциями Арендатора, но не смог. Поэтому я решил обратиться за помощью к конкретному пакету Laravel, который, предположительно, мне нужен.
Tenanti обеспечивает способ решения моей цели, но проблема в том, что я являюсь новичком-разработчиком, не могу полностью понять, как его использовать мое приложение.
Я правильно установил его, я полагаю, что делаю:
composer require "orchestra/tenanti=~3.0"
Добавление этих поставщиков и псевдонимов в файл конфигурационного приложения:
'providers' => [
// ...
Orchestra\Tenanti\TenantiServiceProvider::class,
Orchestra\Tenanti\CommandServiceProvider::class,
],
'aliases' => [
'Tenanti' => Orchestra\Support\Facades\Tenanti::class,
],
Наконец, опубликуем конфигурацию и настроим ее в соответствии с документацией для нескольких баз данных:
php artisan vendor:publish
return [
'drivers' => [
'user' => [
'model' => App\User::class,
'migration' => 'tenant_migrations',
'path' => database_path('tenanti/user'),
],
],
];
В этот момент я все еще расплывчатый, что делать дальше?
Мои сомнения таковы:
- Где будут созданы и сохранены файлы миграции? Я имею в виду, что в моем приложении есть два типа баз данных. Один набор файлов предназначен для основной БД, которая будет хранить всю информацию арендатора, а другие файлы будут для базы данных арендатора. Итак, как и где они будут храниться?
- Я вижу слово "драйвер" в документации, но я не уверен, какой именно драйвер.
- Как я буду обрабатывать аутентификацию для приложения? Я имею в виду, что каждый раз, когда приходит арендатор, мне нужно будет убедиться, что соединение с базой данных изменяется динамически. Как я это сделаю?
- Я попытался пройти через хранилище самого пакета и понять код внутри, но напрасно. Я не очень хорош, когда речь идет о дизайне паттеров, таких как фасады, командная шина, поставщик услуг и т.д., Поэтому я не могу понять поток пакета или понять его.
Я попытался запустить некоторые из команд artisan, которые поставляются с пакетом, например:
php artisan tenanti:install {driver}
php artisan tenanti:make {driver} {name}
Но я получаю такую ошибку:
[InvalidArgumentException] Соединение с базой данных [арендаторы] недоступны.
Где я могу найти ресурсы, чтобы понять, как это сделать?
Ответы
Ответ 1
+1 для @морфофатического ответа, он очень точен на большинстве вещей.
Миграция
Один набор файлов предназначен для основного БД, который будет хранить всю информацию арендатора, а другие файлы будут для базы данных арендатора. Итак, как и где они будут храниться?
Для вашей основной базы данных вы сможете использовать по умолчанию database/migration
и использовать php artisan make:migration
и php artisan migrate
.
Tenanti, однако, будет использовать путь миграции, установленный в конфигурации "драйвер". например:
'path' => database_path('tenanti/user'),
В этом случае миграция будет создана/перенесена из database/tenanti/user
(вы можете выбрать другую папку, и она будет использовать эту папку). После этого вы можете создать новый файл миграции для арендатора-пользователя через php artisan tenanti:make user create_blogs_table
(в качестве примера) и выполнить миграцию через php artisan tenanti:migrate user
(см. Сходство между командой миграции Laravel и Tenanti?).
драйвера
Драйвер - это просто группировка арендатора, возможно, вы группируете его пользователями, компаниями или командой и т.д. И есть вероятность, что вам может потребоваться более одного типа группы для каждого проекта, иначе большую часть времени вы будете используя одиночную "группу" или "драйвер".
Аутентификация или доступ к БД
Как я буду обрабатывать аутентификацию для приложения? Я имею в виду, что каждый раз, когда приходит арендатор, мне нужно будет убедиться, что соединение с базой данных изменяется динамически. Как я это сделаю?
Прежде всего, вам нужно подумать о том, как вы планируете различать каждого арендатора. Большую часть времени я бы видел, как люди предпочитают выбирать субдомен. Поэтому в этом случае вам нужно проверить, принадлежит ли поддомен любому пользователю (путем запроса основной базы данных) с использованием промежуточного программного обеспечения, а затем подключиться к базе данных, которая принадлежит пользователю.
Tenanti не управляет этой частью процесса, потому что у каждого свой стиль по-разному, но мы предоставляем код для динамического подключения к вашему арендатору базы данных из базовой конфигурации базы данных.
Скажем, у вас есть следующая конфигурация:
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => 'primary',
'connections' => [
'primary' => [
//
],
'tenants' => [
'driver' => 'mysql',
'host' => 'dbhost', // for user with id=1
'username' => 'dbusername', // for user with id=1
'password' => 'dbpassword', // for user with id=1
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
],
],
'migrations' => 'migrations',
'redis' => [ ... ],
];
Вы можете выполнить шаг, доступный в https://github.com/orchestral/tenanti#multi-database-connection-setup и добавить следующий код.
<?php namespace App\Providers;
use Orchestra\Support\Facades\Tenanti;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Tenanti::setupMultiDatabase('tenants', function (User $entity, array $template) {
$template['database'] = "tenant_{$entity->getKey()}";
return $template;
});
}
}
Это обеспечит использование базы данных tenant_1
для базы данных user = 1, tenant_2
для пользователя = 2 и т.д.
Итак, как Tenanti обнаруживает, какой пользователь активен?
Здесь вам нужно добавить логику в ваше промежуточное ПО.
$user = App\User::whereSubdomain($request->route()->parameter('tenant'))->first();
Tenanti::driver('user')->asDefaultDatabase($user, 'tenants_{id}');
Ответ 2
Я никогда не использовал этот пакет, но, используя приведенный выше код, я думаю, что он, вероятно, близок к правильному решению. Вероятно, вам все равно придется играть с некоторыми из этих значений, чтобы получить их правильное:
Пути миграции
Поскольку вы используете конфигурацию с несколькими базами данных, я считаю, что вы должны сохранять миграцию в обычном месте, т.е. database/migrations
. Tenanti
затем создаст точную копию базы данных для каждого арендатора в другой базе данных. Однако при запуске php artisan tenanti:install user
он может создать папку под database/
, которая указывает, где вы должны поместить свои миграции.
Что такое "драйвер"?
driver
описывает, будет ли Tenanti
использовать одну или несколько баз данных, какие модели использовать для определения разных арендаторов и где хранить миграции. Это то, что вы указали в конфигурационном файле Tenanti
, который вы использовали выше.
Выбор подключения к базе данных
Вам нужно обновить config/database.php
следующим образом. В приложении normal Laravel
у вас будет настройка соединения с DB следующим образом:
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'sqlite' => [ ...DB connection info... ],
'mysql' => [ ...DB connection info... ],
'pgsql' => [ ...DB connection info... ],
'sqlsrv' => [ ...DB connection info... ],
],
'migrations' => 'migrations',
'redis' => [ ... ],
];
Однако, в случае установки Tenanti
multi-database, вам нужно добавить другую информацию о подключении для каждой базы данных арендатора. Для этого вы добавили новый уровень в ваш конфигурационный файл database.php
(в этом примере предполагается, что вы используете mysql, но вы можете использовать любой БД или даже разные механизмы баз данных для разных арендаторов):
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'tenants' => [
'user_1' => [
'driver' => 'mysql',
'host' => 'dbhost', // for user with id=1
'database' => 'dbname', // for user with id=1
'username' => 'dbusername', // for user with id=1
'password' => 'dbpassword', // for user with id=1
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
'user_2' => [
'driver' => 'mysql',
'host' => 'dbhost', // for user with id=2
'database' => 'dbname', // for user with id=2
'username' => 'dbusername', // for user with id=2
'password' => 'dbpassword', // for user with id=2
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
],
],
'migrations' => 'migrations',
'redis' => [ ... ],
];
Как вы можете видеть, каждый арендатор имеет свой собственный экземпляр базы данных, который может быть расположен на другом хосте и иметь другое имя пользователя/пароль. Tenanti
нужно рассказать, как определить, какую базу данных использовать. Вот что описывает документация по подключению к базам данных. В своем примере они назвали свои базы данных арендаторов, используя acme_{$user->id}
, тогда как в моем примере выше я использовал user_{$user->id}
.
Как я уже сказал, я никогда не настраивал это самостоятельно, но это мои лучшие предположения, основанные на документах, и использование других пакетов этим же разработчиком. Надеюсь, это поможет!