【问题标题】:How to decouple a data core domain from a REST domain?如何将数据核心域与 REST 域解耦?
【发布时间】:2013-11-01 14:00:19
【问题描述】:

我很好奇将核心域实体与 REST 层服务的实体分离的首选方法是什么。

我在这个启发性的 Spring REST 教程 http://spring.io/guides/tutorials/rest/1/ 中看到,不要直接在 REST 层中公开核心域模型是一件好事,因为它应该独立于核心域模型而发展。

核心服务是处理和产生事件。这些事件被视为应用程序的通信端口。核心服务看不到任何 REST 域实体。并且 REST 控制器看不到任何核心域实体。

为了简单起见,我们只考虑一个实体的例子,即订单实体。

本教程展示了如何通过 REST 请求将 Order REST 域类传递给控制器​​。反过来,控制器创建一个 OrderDetails 实体,传递给 Order 处理事件以创建 CreateOrderEvent 事件,然后将其传递给返回另一个 OrderCreatedEvent 事件的服务。控制器最终根据返回的事件创建一个 REST 域 Order 实体,并在响应中发送。

我们可以看到,对于这一实体,核心域实体有一个类,REST域实体有一个类,事件有效负载实体有一个类。

此外,我们可以看到,位于应用程序核心中的事件扩展了一些强烈提醒 HTTP 方法的基本事件。看到这种 REST 之类的东西渗入应用程序核心有点令人惊讶,而我们首先要做的是将应用程序核心与 REST 层分离。

对这种设计或其他设计有什么想法吗?有没有实现这种解耦的首选方法?

感谢您的任何建议。

亲切的问候,

斯蒂芬

我现在还有一个问题......

我应该在与数据域分离的 REST 域上处理实体 NotFoundException 异常还是事件中的 notFoundEntity 事件成员?

发回控制器的事件可以携带一个notFoundEntity成员状态,可以在控制器中使用。

这里是事件notFoundEntity的逻辑:

protected boolean notFoundEntity = false;

public boolean isNotFoundEntity() {
    return notFoundEntity;
}

public static OneAdminEvent notFound(Long id) {
    OneAdminEvent oneAdmiEvent = new OneAdminEvent(id);
    oneAdmiEvent.notFoundEntity = true;
    return oneAdmiEvent;
}

服务根据是否找到实体更新事件成员状态:

Admin admin  = adminRepository.findOne(deleteAdminEvent.getId());            
if (admin == null) {
    return AdminDeletedEvent.notFound(deleteAdminEvent.getId());

在控制器中,调用检查是否已找到实体:

if (adminDeletedEvent.isNotFoundEntity()) {
}

这符合解耦设计。

但是,我不确定解耦事件是否应该携带这些信息。这个信息可以看作是一个异常,一个业务自定义异常。

此外,使用异常可以在事务注释中指定回滚属性:

@Transactional(rollbackFor = NotFoundException.class)

除了一个例外,唯一没有找到的实体逻辑是在服务上,事件不包含任何。

服务现在看起来像:

Admin admin  = adminRepository.findOne(deleteAdminEvent.getId());            
if (admin == null) {
    throw new NotFoundException("No admin was found with the id " + deleteAdminEvent.getId());

使用什么经验法则来决定何时在事件中使用成员状态以及何时使用业务自定义异常?

【问题讨论】:

  • 我不确定答案。但我使用过 openmrs ,这是一个医疗记录系统。 REST 层中有一个单独的模块,它与核心应用程序解耦。你可以看看它的设计。
  • @geekgugi 谢谢你,我会看看他们的 REST 层,应该很有趣。
  • 他们正在使用spring AOP。

标签: rest decoupling


【解决方案1】:

这个示例应用程序更难将 REST 域和核心域层解耦。不仅 REST(又名“视图”)对象与核心(又名“域”)对象完全分离,而且它们的直接通信也通过内部事件驱动架构解耦。核心事件如此强烈地提醒您 HTTP 方法的原因可能更多是由于示例用例的简单性,而不是必要性或设计。这可能是一个例子的危险。 :)

虽然这无疑是一种对应用程序进行分层的好方法,但真正的问题是对于您的特定场景是否有必要。如果您的应用程序非常面向数据(例如,具有很少业务规则的数据输入系统),您可能不需要一组单独的 REST 域对象(就像您可能决定不需要单独的“视图”在传统 MVC 应用程序中的对象)。您可以采用 Spring Data REST 方法(请参阅 Oliver Gierke 的 RESTBucks 示例应用程序)。再说一次,如果您在核心中有一些繁重的业务逻辑并且想要创建一个丰富的域模型,那么您可能最好使用更加解耦的架构。

【讨论】:

  • 谢谢,我想我实际上不需要那么糟糕的解耦。我来看看 RESTBucks 示例。
猜你喜欢
  • 2014-12-22
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 2011-04-30
相关资源
最近更新 更多