在我当前的应用程序中,我需要创建一个 api GET 路由“/inactive-users”,它应该返回已存档的用户(“isArchived”
),并且同时处于非活动状态超过一个月("lastVisitedDate"
字段应早于 new Date() - 1 个月
)。
采用分层架构(控制器/服务/存储库),领域模型贫乏,这种情况下我该怎么办?
我看到有两种可能的方法。
1 - 创建通用存储库方法来获取用户并将我们需要的用户字段传递给它。
@Injectable() export class UserRepository { constructor(private readonly prisma: PrismaService) { } findAll = async ( where: { user: Partial<User>; dateTreshold: Date } ): Promise<User[]> => { const users = await this.prisma.user.findMany( { where: {...user}, lastVisitedDate: { lt: dateTreshold }; // lt - less than ); return users.map(user => new User(user)); } } @Injectable() export class UserService { constructor(private readonly userRepository: UserRepository) {} getInactiveUsers = async () => { return this.userRepository.findAll( { where: {user: {isArchived: true}, dateTreshold: "// calculatedDate //"} ) } }
2 - 准确地创建存储库方法来检索不活动的用户,该方法将知道它应该请求哪些字段。
@Injectable() export class UserRepository { constructor(private readonly prisma: PrismaService) { } getInactiveUsers = async (): Promise<User[]> => { const users = await this.prisma.user.findMany( { where: {isArchived: false, lastVisitedDate: { lt: "// calculatedDate //" }}; // lt - less than ); return users.map(user => new User(user)); } } @Injectable() export class UserService { constructor(private readonly userRepository: UserRepository) {} getInactiveUsers = async () => { return this.userRepository.getInactiveUsers() } }
哪种方式更好? 第一个对我来说看起来不错,因为在这种情况下,存储库对“非活动”用户的域理解一无所知。但与此同时 - 构建这样一个响应式方法可能相当困难。
第二种方式更容易构建,但同时 - 它具有一些“业务”逻辑理解,并且知道不活动用户是那些 "isArchived"
等于 false
的用户。而且,这个存储库方法知道我们需要使用的天数。
在这种情况下应该选择哪个选项?或者也许还有其他方法来构建这个东西?
分离此问题的正确方法是存储库仅了解存储库中的数据元素。这并不意味着您的存储库中不能有多个入口点,可能有许多不同的查询都访问相同的“表”。
这并不意味着您需要像第一种方法那样的完整 QBE,请保持简单。有一个封装数据库层位的查询,但仍然要求它需要的东西。
在这种情况下,您应该有一个传递 isArchived 和 lastVisitedDate 参数的签名。类似 QueryUsersByStatusAndLastVisited 之类的东西。这样,存储库可以处理与检索数据有关的所有位,但没有关于为什么检索它们的逻辑。它将是“哑巴”的,所有智能位都封装在服务层。