use*_*450 5 loopbackjs loopback4
在基于模式的多租户应用程序中,通常有一个具有多个模式的数据库。一种模式是存储通用应用程序数据的主要模式,一种用于应用程序的每个租户。每次有新客户注册到系统时,都会在数据库中自动创建一个新的隔离模式。这意味着,模式是在运行时创建的,并且事先不知道。客户的模式是根据客户的域命名的。当请求进入系统时,用户将得到验证并使用主模式上的数据选择模式。然后大多数/所有后续数据库操作都转到租户特定的模式。如您所见,我们要使用的模式仅在运行时才知道。
如何在运行时选择模式?我们正在使用 postgres 连接器。我们应该能够在运行时切换模式。
另一个问题是如何为不同的租户运行迁移?
db-schema 需要以请求范围的方式设置,以避免为可能属于其他客户的其他请求设置架构。为整个连接设置架构不是一个选项。
您可以在运行时创建 DefaultCrudRepository (使用遗留杂耍模型和数据源的 CRUD 存储库的默认实现),它需要两个参数
现在使用所需的设置实例化数据源,包括您要使用的架构然后将您的模型和数据源提供给 DefaultCrudRepository 实例,如下所示:-
const ds = new PostgresDataSource({
connector: 'postgresql',
host: 'some host',
port: 'some port',
user: 'some user',
password: 'password',
database: 'database',
schema: 'schema for that particular tenant',
});
const repo = new DefaultCrudRepository(SomeModel, ds);Run Code Online (Sandbox Code Playgroud)
然后使用这个存储库来执行查找、创建等方法。有一个示例实现 https://github.com/hitesh2067/dynamic-schema-example
我已将架构作为查询参数传递,但您可以使用任何其他方式来提供架构
更新的解决方案:-
现在 Loopback 已经为应用程序上下文和请求上下文提供了中间件和更好的上下文分离。我们可以使用它动态连接到任何数据源(希望连接器安装在 package.json 中)并将其绑定到应用程序上下文,然后将该绑定临时绑定到 UserRepository (或任何多租户存储库)指向的数据源在请求上下文中。
示例写在 https://github.com/dev-hitesh-gupta/loopback4-multi-tenant-multi-datasource-example
实施会像
const tenant = await this.getTenant(requestCtx);
if (tenant == null) return;
const tenantData = await this.tenantRepo.findById(tenant.id);
requestCtx.bind(CURRENT_TENANT).to(tenantData);
const tenantDbName = `datasources.multi-tenant-db.${tenantData.id}`;
// adding datasource if not present
if (!this.application.isBound(tenantDbName)) {
const tenantDb = new juggler.DataSource({
name: tenantDbName,
...tenantData.dbConfig,
});
this.application.bind(tenantDbName).to(tenantDb).tag('datasource');
}
// Pointing to a default datasource in request context
requestCtx
.bind('datasources.multi-tenant-db')
.toAlias(tenantDbName);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
738 次 |
| 最近记录: |