【问题标题】:Repository pattern - Do I "need" a service layer in REST API? [closed]存储库模式 - 我是否“需要”REST API 中的服务层? [关闭]
【发布时间】:2019-10-27 20:48:49
【问题描述】:

我提出这个问题是为了征求你对此事的看法,看看我是愚蠢还是迂腐。


问题(tl;dr;)

当存储库层已经可以通过查询以更快的方式完成大部分事情(如 FindUserByID),而服务必须手动完成所有这些事情时,我是否“需要”服务层(作为良好实践)效率低得多且超级手动的方式?

描述(对于那些想了解我的动机的人)

所以,我一直在处理清洁架构,这很棒,但不适用于 REST 架构。因为,清洁架构实际上是由控制器层构成的,而 RPC 是处理控制器的层,而不是 REST。 REST 处理资源。 所以,我删除了“控制器”层,我也在考虑是否真的需要一个“服务”层。

所以 REST 需要 “服务” 和/或 “存储库”。奇怪的是,我认为这两个重叠。我知道服务应该处理“业务规则”。但事情是这样的:

存储库可以使用服务完成相同的工作,但存储库可以以更有效的方式完成相同的工作

由于允许存储库与数据库直接通信,因此它们可以使用数据库查询(sql 或 nosql 查询)。哪些更编写效率更高,更阅读效率更高,更性能效率更高

服务方式:

比如说,你需要通过他的 ID 找到一个用户,然后从他的好友列表中根据他的名字选择一个特定的朋友。

  • 您从 repository 获取所有用户
  • 您为所有用户创建了一个循环
  • 您创建了一个条件,您可以在其中检查哪个用户拥有您想要的 ID
  • 您为好友列表中的所有好友创建了一个循环
  • 你做了一个条件来检查朋友的名字

总结?喜欢 20-30 行代码和更慢的性能?

存储方式:

filter := bson.M{
    "_id": id,
    "friendlist.name": friendsName,
}
projection := bson.M{
    "friendlist": 1
}
friend, err := mongoDb.find(filter, projection)

总结?就像 3-4 行代码和 99% 的数据库性能。

那么,“服务层”部分是否真正需要?当存储库本身已经可以更高效地完成所有工作时,将其拆分为服务层和存储库层是否有任何真正的架构优势?

【问题讨论】:

  • 正如您的第一句话所示,这个问题是基于意见的。因此,它是题外话。
  • 我同意,但即使是基于意见的问题也可以获得最佳答案。我看不出它是如何“离题”的,您仍然可以给出一个非常主观的答案来指导我和其他可能有相同问题的人。
  • @Eksapsy 如果它主要是基于意见的,那就离题了。也就是没有办法给出权威的答案。
  • 这不是给出你的意见,而是给出指导。如果你不想,你不必发表你的意见。当有人问你“买什么游戏机”时,你不必告诉他“PS4”。你可以直接问他的需求是什么,从而让他得出自己的结论,而不必给出自己的意见。

标签: rest architecture repository-pattern


【解决方案1】:

对于像“通过 id 检索用户”这样的小样本,也许不需要服务层。

但是,在更大的应用程序中 - 事情要复杂得多。一些例子:

  • 用户存储在一个单独的微服务中分解,需要通过 gRPC/HTTP 查询用户。
  • 引入了缓存层来缓存需要缓存失效的剩余资源(memcached、Redis 等)。
  • Rest-layer 需要写入多个版本,有重大改动,但数据库是一样的。
  • 当系统中发生某些事情时,您可以引入事件总线来触发事件。
  • 您有大量业务逻辑,需要不依赖数据库连接的单元测试。

将事物分层分开将使测试、调试和更改变得更加容易。如果您遇到数据库查询性能不佳的问题,您可以通过构建更好的查询在存储库层解决该问题,而无需担心其他部分。如果逻辑有bug,可以不依赖数据库修复,只需构建单元测试用例,更新服务层即可。

对于带有简单用例的单人表演来说,分层很烦人。对于一个应该与许多不同的客户和多个人一起工作很长时间的应用程序来说,这是必不可少的。

而且我不同意您对“服务方式”与“存储库方式”的描述。您当然应该在存储库中提供优化的方法以供服务使用,本质上是:Repository:GetSingleUserById 应该在那里并且在任何情况下都应该进行优化。

【讨论】:

  • 好吧,所以服务层存在的原因不是提供数据库无论如何都可以做的事情,也不是包括业务逻辑(因为数据库在这方面更好,更高效,正如我演示的那样) ,但要提供缓存、调用单独的微服务等逻辑。我说对了吗?只是为了确保我 100% 正确理解这一点。您的答案是理想的、非常有用的信息和对任务的主观性,谢谢。
  • 一些业务逻辑在数据库附近/内部执行得非常好,而其他业务逻辑则不然。尤其是当数据来自多个来源(其他微服务、其他组织的各种 API、缓存等)时。假设您要根据大量金融交易创建税务报告。我会从 repo 中查询相关交易并在服务层进行计算。
【解决方案2】:

当存储库层已经可以通过查询以更快的方式完成大部分事情(如 FindUserByID),而服务必须手动完成所有这些事情时,我是否“需要”服务层(作为良好实践)效率低得多且超级手动的方式?

不,你没有。通过不必要的层路由您的数据以获取架构分数并不会为您提供更易于维护或交付成本更低的代码。

另请参阅命令查询职责分离 (CQRS)。

【讨论】:

  • 通过说 CQRS,您是否表示可以直接在控制器中使用存储库来读取和使用需要一些业务逻辑的突变的服务?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
  • 1970-01-01
  • 2012-12-09
相关资源
最近更新 更多