【问题标题】:Is it possible to do DDD and REST interface and language mapping?是否可以做 DDD 和 REST 接口和语言映射?
【发布时间】:2014-09-25 23:50:12
【问题描述】:

REST 有一个统一的接口约束,下面是一个非常压缩的基于意见的格式。

  • 您必须使用 HTTP、URI、MIME 等标准...
  • 您必须使用超链接。
  • 您必须使用 RDF 词汇对数据和超链接进行语义注释。
  • 您执行所有这些操作是为了将客户端与服务的实现细节分离。

据我所知,带 CQRS(或不带 CQRS)的 DDD 非常相似。

  • 您可以通过 CQRS 定义与域模型交互的接口。该接口由命令和查询类组成。
  • 您可以通过 DDD 定义域事件以将域模型与持久性细节分离。
  • 通过 DDD,每个有界上下文都有一种普遍存在的语言来表达语义。
  • 您执行所有这些操作是为了将域模型与外界完全分离。

是否可以将 REST 统一接口映射到由命令和查询以及域事件定义的域接口? (所以会自动生成 REST 服务代码。)

是否可以将链接数据语义映射到普遍存在的语言? (因此您无需定义非常相似的术语,只需查找并重用现有词汇即可。)

请在您的答案中添加一个非常简单的映射示例,为什么是或为什么不是!

【问题讨论】:

  • 这让我想起了裸体物体 (nakedobjects.org)。我看到还有一种叫做restful objects的东西(restfulobjects.org):infoq.com/articles/Intro_Restful_Objects
  • 实际上命令、域事件等的属性不应该被隐藏。它们是代表领域模型接口的 DTO。所以我认为裸体物体会做一些完全不同的事情。 RESTful 对象得到了错误的映射:“在 Restful Objects 规范中,每个域对象都是一个资源”。但我没有更多的帮助,我不想写答案。

标签: rest domain-driven-design cqrs


【解决方案1】:

我认为这是不可能的。我相信有一个术语可以描述这个问题,它叫做ontology alignment

在这种情况下至少有 3 个本体:

  • 领域模型的通用语言 (UL)
  • REST 服务的应用程序特定词汇 (ASO)
  • 应用特定词汇使用的链接开放数据词汇 (LODO)

所以我们至少有 2 个对齐方式:

  • UL:ASO 对齐
  • ASO:LODO 对齐

我们的问题与 UL : ASO 对齐有关,所以我们来谈谈这些本体。

UL 是面向对象的,因为我们谈论的是 DDD 和领域模型。所以大多数领域对象entitiesvalue objects 都是真实的对象而不是数据结构。它的非面向对象部分是域模型接口上的command+domainEventquery+resulterror 等DTO。

相比之下,ASO 是严格程序化的,我们使用一组标准方法(程序)来操作资源(数据结构)。

所以从我的角度来看,我们正在谈论 2 个非常不同的事情,我们有以下选择:

  • 使 ASO 更加面向对象 -> RPC
  • 使 UL 不那么面向对象 -> 贫乏的领域模型

所以在我看来,我们可以做以下事情:

  • 我们可以通过 CRUD 自动将实体映射到资源并将命令映射到操作,例如,HydraBundle 使用活动记录执行此操作(我们可以使用 DDD 和不使用 CQRS 执行相同操作)
  • 我们可以通过复杂的域模型手动将命令映射到操作

    • POST transaction {...} 操作会导致SendMoneyCommand{...}
    • GET orders/123/total 操作会产生OrderTotalQuery{...}
  • 我们不能通过复杂的领域模型将实体映射到资源,因为我们必须定义新的资源来描述一个新的服务或一个新的实体方法,例如

    • 操作POST transaction {...}可以得到account.sendMoney(anotherAccount, ...)
    • GET orders/123/total 操作可以在读取数据库上产生 SQL 查询,而无需接触单个实体

我认为在 DDD+CQRS 和 REST 之间做这种本体对齐是不可能的,但我不是这个主题的专家。我认为我们可以做的是创建一个具有资源类、属性和操作的特定于应用程序的词汇,并将操作映射到命令/查询,并将属性映射到命令/查询属性。

【讨论】:

    【解决方案2】:

    您在这里提出了一些有趣的问题。

    首先我不太同意

    通过 DDD,您可以定义域事件以将域模型与 持久性细节。

    我认为您可能会将Event Sourcing ES 与 DDD 混淆,ES 可以与 DDD 一起使用,但它非常可选,实际上您应该在选择它作为持久性机制之前多考虑一下。

    现在你的大部分问题是,如果是,REST 和 DDD 是否相处得很好?

    我的看法,是的,他们确实相处融洽,但通常你不想通过 REST 接口公开你的域模型,你想在它之上构建一个抽象然后公开它。

    你可以参考这个答案here,了解更多细节。

    但是我不能推荐足够多的 Implementing Domain-Driven Design 书,第 14 章应用程序可以公平地处理您的问题。

    我无法比这本书更彻底地解释它,因此推荐你去那里:)

    【讨论】:

    • “我认为您可能将 Event Sourcing ES 与 DDD 混淆了” - 不,通过 DDD,您必须将域模型与数据存储分离,或者我们谈论的是活动记录而不是域模型。使用领域事件是最好的方法。 “现在你的大部分问题是,REST 和 DDD 是否相处得很好,如果是的话,如何相处?”他们相处得很好。问题是是否可以根据域模型自动生成 REST 部分......
    猜你喜欢
    • 1970-01-01
    • 2014-08-21
    • 2011-11-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 2018-05-26
    相关资源
    最近更新 更多