如何将数据核心域与REST域分离?

时间:2013-11-01 14:00:19

标签: rest decoupling

我很想知道将核心域实体与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层分离时,这有点令人惊讶。

有关此设计或其他设计的想法吗?有没有实现这种脱钩的首选方法?

感谢您的任何建议。

亲切的问候,

的Stephane

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

我是否应该在与数据域分离的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());

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

1 个答案:

答案 0 :(得分:2)

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

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

相关问题