如果您有服务层,Prisma 是否需要存储库模式?

mik*_*see 5 architecture repository typescript

因为 Prisma 有点像 ORM,它已经为您提供了访问数据库中数据的强大工具,这是需要的存储库模式。我读过相互矛盾的意见,基本上它似乎是“这取决于……也许……也许不是”这没有帮助。

因此考虑到以下情况:

export class AvatarPartRepo extends BaseRepo<"avatar_part"> {
  getAllForUser(owningUserId: string): Promise<avatar_part[]> {
    return this.model.findMany({ where: { owningUserId } });
  }

  findOneForUser({
    owningUserId,
    definitionId,
  }: {
    definitionId: string;
    owningUserId: UUID;
  }): Promise<avatar_part | null> {
    return this.model.findFirst({ where: { definitionId, owningUserId } });
  }

  doesUserHave({
    owningUserId,
    definitionId,
  }: {
    definitionId: AvatarPartDefinitionIds;
    owningUserId: UUID;
  }): Promise<boolean> {
    return this.findOneForUser({ definitionId, owningUserId }).then((o) => o != undefined);
  }

  getDefinitionIdsForUser(owningUserId: string): Promise<string[]> {
    return this.model
      .findMany({ where: { owningUserId }, select: { definitionId: true } })
      .then((r) => r.map((x) => x.definitionId));
  }

  create(input: {
    owningUserId: UUID;
    definitionId: AvatarPartDefinitionIds | string;
  }): Promise<avatar_part> {
    return this.model.create({ data: input });
  }
}
Run Code Online (Sandbox Code Playgroud)

这个存储库应该存在吗?或者它应该存在于“服务层”中?

问题是,如果我最终同时拥有服务层和存储库,我最终会将一堆东西“转发”到服务层中的存储库,这使它感觉有点多余。

export class AvatarPartsService extends BaseService {

  getAllForUser = this.repos.avatarParts.getAllForUser.bind(this.repos.avatarParts);

  doesUserHave = this.repos.avatarParts.doesUserHave.bind(this.repos.avatarParts);

  create = this.repos.avatarParts.createPart.bind(this.repos.avatarParts);

  findOneForUser = this.repos.avatarParts.findOneForUser.bind(this.repos.avatarParts);

}
Run Code Online (Sandbox Code Playgroud)

服务层确实存在,因为据我了解,“视图”层不应该直接与存储库通信?

如果答案是“不,这不应该存在”,那么如果您使用 Prisma,是否应该存在任何存储库?

eug*_*vnk 0

在我看来,就关注点分离而言,这可能是件好事。
服务层-业务逻辑,存储层-数据访问逻辑。
想象一下,如果您的用户注册时间不到 1 天,则无法上传头像。
在这种情况下,您的代码可能如下所示:

class AvatarPartsService {
  create(userId) {
    const timeElapsedSinceUserRegistration = await this.getTimeSinceUserRegistration(userId);
    if (timeElapsedSinceUserRegistration < 3600) throw new NotMatureUserError();
    
    this.avatarPartsRepo.create(); 
  }
}
Run Code Online (Sandbox Code Playgroud)

如果将上面示例中的this.avatarPartsRepo.create()代码替换为,我们会遇到下一种情况。this.prisma.avatarParts.create

我们有一个管理员角色(和“AdminsService”)。他具有为任何用户创建头像的功能,而不取决于其注册时间。

在这种情况下,我们无法使用,AvatarPartsService.create因为它不会为“太年轻”的用户创建头像。
所以我们必须重复编写this.prisma.avatarParts.create或者只是重用我们的this.avatarPartsRepo.create.