【问题标题】:Is it good to return domain model from REST api over a DDD application?通过 DDD 应用程序从 REST api 返回域模型是否很好?
【发布时间】:2012-06-12 05:06:14
【问题描述】:

如果您要在 DDD 应用之上为 CRUD 设置一个 REST 层,您是否会让 REST 层吐出域模型(就数据而言)(比如 GET)?

【问题讨论】:

    标签: rest domain-driven-design


    【解决方案1】:

    通常,您希望能够更改域对象(例如,当您了解有关域的新知识时),而不必更改系统的公共接口/API。反过来也是一样:如果需要对公共接口进行更改,您就不必更改域模型。

    所以从这个角度来看,我永远不会在公共接口上按原样公开我的域对象。相反,我会创建作为公共接口一部分的数据传输对象 (DTO)。这样,对我的域和公共 api 的更改可以独立更改。

    【讨论】:

    • 是否可以基于带注释的 DTO(命令、查询、域事件)生成 REST 部分,如果可以,如何生成?请在这里回答:stackoverflow.com/questions/26049934/…
    • 这有点偏颇。没有必要在 DDD 中人为地从域中“保护”用户:一些概念可能在建模时就“通过”,而另一些则被隐藏(除非模型不太正确)。此外,在原始帖子中“REST over DDD”是有问题的。首先应该(大多数时候)在域之上有某种应用层。这意味着,域对象已经分离。
    • @RomanSusi 我不确定您所说的“保护用户远离域”是什么意思;你能详细说明一下吗?我绝对同意公共接口将处理与域相同的概念。我的观点不是关于将域从公共 REST 接口的消费者中“抽象”出来,而是关于将域对象的更改与此公共 REST 接口的更改解耦。
    • @Marijn 好的,也许我读错了。我只是想当然地认为运输特性/细节大多无关紧要。但是,并非所有对域的更改都可以使用公共 API,是否有额外的抽象:只有向后兼容的。我认为,如何使用 REST 层也可能是相关的。它可能只是弥合了前端-后端的差距,在这种情况下,在域方面进行操作是没有问题的。 (但通常有框架)
    【解决方案2】:

    您不应公开 DDD 模型。这是绝对正确的,因为 SOA 前端不应该向客户端公开实现细节。您的用户应该依赖于一个业务功能,而不是一个实现细节……但这假设了一个很好的设计,将几个可能是异构的应用程序联合到一个 SOA 总线中。

    我想补充一下答案,因为提到 CRUD 接口让我认为这可能是 SOA 滥用的一个案例,其中 SOA 原则用于粘合应用程序的各个层,而不是应用程序网络。 SOA 是企业沟通其系统的一种方式,而不是一种实现 MVC 的方式!如此简单却又如此被误解。例如,仅仅因为您的前端 GUI 使用服务来访问后端,您就没有“SOA 应用程序”……这意味着什么。

    如果这是用于粘合层的 SOA 案例,请修改您的设计并为该抽象级别使用适当的设计架构。否则你会误解这里关于不暴露 DDD 模型和不使用 CRUDY 的建议,你最终肯定会为服务接口创建一个单独的域模型,然后你必须映射到 DDD,这太复杂了你将需要使用推土机之类的东西来映射具有不同名称的同一事物,等等,直到我们最终得到一个臃肿的无法维护的混乱......

    .. 小心点。

    -亚历克斯

    Redzedi 说的太对了,我们需要澄清一下......

    就像所有事情一样,做起来比说起来要复杂得多。序列化一个复杂的域模型可能非常困难,以至于您最终要么不将任何逻辑放入域中,贫血模型反模式 (http://martinfowler.com/bliki/AnemicDomainModel.html),要么有一个单独的贫血模型持久性,即 DTO。

    我不知道什么是最糟糕的,但两种选择都很糟糕。您应该将模型中的逻辑放入模型中,并且您应该能够在任何地方直接序列化。

    根据我多年使用领域模型的经验,我相信最好的事情是中间的一点。是的,正如 Fowler 和 Evans 所说,业务对象应该带有逻辑,但不是所有(http://codebetter.com/gregyoung/2009/07/15/the-anemic-domain-model-pattern/)都有一点贫血好的服务层是最好的。

    例如,发票应了解其项目并具有计算其总额的程序,这取决于项目。但是发票的项目不需要知道发票。那么当一个项目的成本发生变化时,它是否应该有一个指向父发票的指针作为循环引用并调用发票的总计算过程?

    我相信不会。我认为这是服务层的任务,它应该首先接收事件然后编排过程,而不必为了实现目的将所有业务对象耦合在一起,也不必违反业务交互规则,而这正是领域模型的用途。

    -亚历克斯

    【讨论】:

    • 感谢 Alex,SOA 与否,将数据从域模型映射到某个 DTO 以便视图可以消费的问题将始终存在,不是吗?
    • 您好 Redzedi,在我个人看来,我尝试将域模型直接映射到数据库。域模型是数据模型。所以我只有一个用于用户界面和数据库的业务对象。
    • 你说 ALex 是一件非常重要的事情,对我来说似乎很有吸引力,但我听说过各种各样的事情,Marijn 上面所说的很多人都相信,但根据我的经验,这会导致不同层中有许多外观相似的 Java 类,其中任何后续添加都会导致大量教条式代码映射。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2021-09-29
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2013-10-15
    相关资源
    最近更新 更多