4

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

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

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

为简单起见,让我们仅考虑一个实体的示例,即 Order 实体。

本教程展示了如何通过 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());

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

4

1 回答 1

2

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

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

于 2013-11-01T17:25:40.973 回答