2013-11-01 22 views
3

我很好奇从REST层服务的实体中分离核心域实体的首选方式是什么。如何从REST域中分离数据核心域?

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

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

为了使事情更简单,让我们考虑只有一个实体Order实体的例子。

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

我们可以看到,对于这一个实体,核心域实体有一个类,REST域实体有一个类,事件有效载荷实体有一个类。另外,我们可以看到,坐在应用程序核心中的事件扩展了一些基本的事件,这些事件强烈地提醒了HTTP方法。看到这个REST就像渗透到应用程序核心中的东西,当我们试图首先做的事情是将应用程序核心与REST层分离时,有点令人惊讶。

任何想到这个设计或一些替代设计?是否有任何实现这种解耦的首选方式?

感谢您的任何建议。

亲切的问候,

斯特凡

一个额外的问题,我现在有...

我应该去实体NotFoundException异常或在事件notFoundEntity事件成员,一个REST域从数据域中解耦?

发送回控制器的事件可以携带可用于控制器的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()); 

什么凭经验使用决定何时在事件中使用的成员国以及何时使用业务自定义异常?

+0

Iam不知道答案。但我曾经与openmrs这个医疗记录系统合作过。 REST层中有一个与核心应用程序分离的独立模块。你可以看看它的设计。 – geekgugi

+0

@geekgugi谢谢,我会看看他们的REST层,它应该很有趣。 – Stephane

+0

他们正在使用弹簧AOP。 – geekgugi

回答

2

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

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

+0

谢谢,我想我并不需要那么差才能解耦。我会看看RESTBucks示例。 – Stephane