使用服务模式和使用独立存储库 Spring Data REST 有什么区别?

kwo*_*ski 12 java spring spring-data-rest

单独使用 Spring Data REST 存储库并围绕它实现“服务”模式(即ItemServiceItemServiceImpl等等)有什么区别?

乍一看,功能或多或少相同,不同之处在于服务方法允许更好的定制,但它也会产生大量的样板代码(实现和控制器)。这是使用这两种方法的示例(外观PaymentCreditCard实体) - Oliver Drotbohm 的 RESTBucks。

那里的支付抽象使用使用的“服务”模式(PaymentService、PaymentImpl 然后 PaymentController 和 web 文件夹中的所有方法),而订单直接通过 Spring Data REST 公开。

Oli*_*ohm 6

tl;博士

支付功能处于更高的抽象级别,因为它不遵循既定的 HTTP 资源模式(集合资源、项目资源,一般来说:此处描述的那些),因此需要自定义服务实现。相比之下,订单聚合的生命周期确实遵循这些模式,因此除了 Spring Data REST 暴露和一些自定义之外不需要任何东西。在此处查找有关两个实现部分如何相互关联的概念概述。

细节

这是一个很好的问题。示例应用程序旨在展示 API 的不同部分如何由不同的需求驱动,以及您如何使用 Spring Data REST 来处理遵循既定模式的部分,同时通过更高级别的方面来增强它需要表达业务流程。

该应用程序分为两个主要部分:以Order通过不同阶段进行的聚合为中心的订单处理。可以在此处找到有关这些的概念概述。因此,我们用于订单的部分 API 将遵循标准模式:可过滤的收集资源以查看所有订单、添加新订单等。这就是 Spring Data REST 的亮点。

支付部分不同。它需要以某种方式融入订单处理的 URI 和功能空间。我们通过以下步骤实现:

  1. 我们在专用服务中实现所需的功能。存储库交互与必要的抽象级别不匹配,因为我们必须验证对OrderPayment聚合的业务约束。该逻辑需要存在于某个地方:在服务中。
  2. 我们通过Spring MVC 控制器公开该功能,因为我们(目前)不需要像列出所有付款这样的标准模式。请记住,该示例围绕订购流程建模,而不是会计后端。支付资源被混合到订单的URI空间:/orders/{id}/payment
  3. 我们使用超媒体元素来指示何时可以通过添加指向这些资源的链接有条件地触发功能,以便客户端可以使用这些元素的存在或不存在来决定提供哪些 UI 可供性来触发该功能。

以下是我认为这种方法的优点:

  1. 您只需手动编码从业务角度来看很重要的部分。无需为遵循完善模式的 API 部分实现大量样板代码。
  2. 客户不需要关心接缝的确切位置。使用超媒体元素,API 对客户端来说只是一回事。服务器甚至可以将支付资源移动到不同的 URI 空间或不同的服务。

资源

该套牌讨论了我详细描述的内容。这是它的视频记录。如果你有兴趣特别是对超媒体驱动的更高层次的想法,我认为这个幻灯片甲板,太