目标
我正在尝试使用 Feathers JS 构建一个多租户应用程序。登录时,租户 ID 将包含在请求中。从那时起,租户 ID 将从user
带有请求参数的字段中获取。每个用户都有这个tenantId
字段。
在 MongoDB 中,我对每个租户的每种数据类型都有一个唯一的集合。集合名称看起来tenantId.documents
像tenantId.users
问题
通过feathers generate service
CLI 命令生成的服务如下所示:
export class Documents extends Service {
//eslint-disable-next-line @typescript-eslint/no-unused-vars
constructor(options: Partial<MongoDBServiceOptions>, app: Application) {
super(options);
const client: Promise<Db> = app.get('mongoClient');
client.then(db => {
this.Model = db.collection('documents');
});
}
}
如您所见,生成Service
的 s 在实例化期间似乎需要它们的集合名称(在本例中为“文档”)。通常,这是有道理的,因为它可以节省await
调用app.get("mongoClient")
但是,由于我需要根据 User 动态更改从哪个集合中读取tenantId
,因此这对我不起作用。
我实现了以下内容:
export class Documents extends Service {
client: Promise<Db>
//eslint-disable-next-line @typescript-eslint/no-unused-vars
constructor(options: Partial<MongoDBServiceOptions>, app: Application) {
super(options);
this.client = app.get("mongoClient");
}
async create(data: IDocumentData, params: Params) {
const db: Db = await this.client;
this.Model = db.collection(`${params.user!!.organizationId}.documents`);
return super.create(data, params);
}
}
问题是这些:
- 我需要
await this.client
每个请求,即使在用户实际向该服务发出请求时承诺可能已经实现 Service
即使我几乎不需要添加任何真正的功能,我也必须实现父级的每个方法。
问题
解决这个问题的最简单的方法是什么?
- 我不想覆盖每个服务中我需要的每个方法
- 我看不到用中间件或钩子来处理这个问题的方法。
- 我也不认为有必要在我的应用程序中为每个租户创建一个服务实例。看起来很浪费,因为我不需要根据租户 ID 发出任何额外的外部请求,我只需要更改集合
在 Feathers 中是否有一个好的、漂亮的方法来做到这一点?