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

What are the differences of using service pattern and using standalone repository Spring Data REST?

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

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

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

您的服务包含所有逻辑,但存储库层尽可能愚蠢。它的任务是一个特定的操作(例如保存,编辑)。

Spring 数据是一种额外的便利机制,用于与数据库实体交互、将它们组织在存储库中、提取数据和更改数据。在某些情况下,在其中声明接口和方法就足够了,无需实现它。 P.S 如果你正在创建一个简单的 crud

,这是一个不错的选择

tl;博士

支付功能处于更高的抽象级别,因为它不遵循已建立的 HTTP 资源模式(集合资源、项目资源,一般来说:描述的那些 here) and thus warrants a custom service implementation. In contrast, the lifecycle of the order aggregate does indeed follow those patterns and thus doesn't need anything but Spring Data REST exposure plus a few customizations. Find a conceptual overview about how the two implementation parts relate to each other here

详情

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

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

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

  1. 我们在 dedicated service 中实现了所需的功能。存储库交互不符合必要的抽象级别,因为我们必须验证 OrderPayment 聚合上的业务约束。该逻辑需要存在于某个地方:在服务中。
  2. 我们通过 a Spring MVC controller 公开该功能,因为我们(目前)不需要标准模式,例如列出所有付款。请记住,该示例以订购流程建模为中心,而不是会计后端。支付资源混合到订单的 URI space 中:/orders/{id}/payment.
  3. 我们使用超媒体元素来指示何时可以通过 adding a link 有条件地指向这些资源来触发功能,以便客户可以使用这些元素的存在与否来决定 UI 可供性提供触发该功能。

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

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

资源

This deck discusses what I described in detail. Here's a video recording of it. If you're interested in the higher level ideas of especially the drive towards hypermedia, I suggest this slide deck,也是