DDD / CQRS / ES使用图形数据库实现聚合成员,也使用立即一致的readModel作为实体集合

时间:2015-11-10 15:30:34

标签: domain-driven-design graph-databases cqrs event-sourcing

抽象

我正在为我的应用程序建模通用授权子域。这些要求非常复杂,因为它需要处理多租户,分层组织结构,资源组,用户组,权限,用户可编辑权限等。它是RBAC(分配给角色的用户,具有权限的角色,权限可以执行命令)与基于声明的身份验证的混合。

问题

在检查业务规则不变量时,我必须遍历权限" graph"查找用户对环境中的资源执行命令的权限。遍历深度在多个维度上是任意的。

我可以使用代码对此进行建模,但最好使用图形数据库来表示,因为此聚合上的查询/更新会更快。此外,它会降低代码本身的复杂性。但这需要图形数据库立即保持一致。

仍然,我需要使用CQRS / ES,并启用分布式架构。

因此图数据库需要

  • 立即一致

这引入了一些缺点

  • 从事件存储加载事件时,我们每次都必须重建图数据库
  • 或者,我们必须介绍某种图形数据库快照
  • 与图表数据库通信时的开销

但它有优势

  • 降低执行复杂查询的复杂性
  • 比使用代码
  • 更快地解决复杂查询
  • 图表数据库非常适合这项工作

为什么会这个问题?

在我建模的其他聚合中,我经常有一个EntityList实例或EntityHierarchy实例。它们基本上是子实体的有序/分层集合。他们的实施是任意的。它们可以支持索引,键值对,动态数组等任何内容。只要它们实现我为它们声明的接口。我经常在这些实体(列表)上使用findById()findByName()等方法。这些方法类似于可以在数据库上执行的方法,但它们在内存中执行。

那么,为什么不能实现这样一个可以绑定到数据库的列表呢?例如,我没有TMemoryEntityList,而是TMySQLEntityList。在目前的情况下,可能需要在TGraphAuthorizationScheme聚合内部生成TOrgAuthPolicy的实现。只要它的行为类似于集合,并且它可以迭代并支持定义的接口。

我在Node.js上使用JavaScript构建我的应用程序。有一个名为LevelGraph的内存实现。也许我也可以使用它。但是,让我们继续。

提案

我知道在DDD术语中,基础设施不应泄漏到域中。这就是我想要阻止的。这也是我提出这个问题的原因之一,是我第一次遇到这样的技术需求,我问的是那些习惯于应对这类问题的人提出一些建议

集合的界面是IAuthorizationScheme。实现必须支持深度遍历,授权查找等。这是我正在考虑通过支持图形数据库来实现的接口。

序列:

1当用户要求执行命令时,我首先验证他。我找到他的组织,并要求OrgAuthPolicyRepository加载他的组织的相应OrgAuthPolicy

  1. OrgAuthPolicyRepositoryEventStore加载事件。

  2. OrgAuthPolicyRepository创建了一个新的OrgAuthPolicy,其中包含依赖注入的TGraphAuthorizationScheme实例。

  3. OrgAuthPolicyRepository将所有先前的事件应用于OrgAuthPolicyGraphDatabase依次调用图数据库上的查询以将IAuthorizationScheme的状态与聚合同步。

  4. 命令处理程序执行业务规则验证检查。其中一些可能包含对汇总IAuthorizationScheme的检查。

  5. 已验证业务规则,并分派域事件。

  6. 聚合处理此事件,并将其应用于自身。这可能包括对{{1}}。

  7. 的更改
  8. eventBus将事件调度到读取端的所有侦听eventHandler。

  9. 示例:

    enter image description here

    简历

    使用外部数据库(例如图形数据库)实现实体是否可以/可取,以便更容易实现?如果是,是否有此类实施或指南的示例?如果没有,使用这种技术会有什么缺点?

1 个答案:

答案 0 :(得分:2)

要解决您的任务,我会考虑从上到下的以下变体:

  1. 通过使用安全框架或身份来降低任务复杂性 管理解决方案。开箱即用的identity management solution可能会有所作为。如果它没有看看框架,以帮助您实现自己的。不幸的是,我对Node.js世界的建议不太熟悉 你呢。在Java世界中,可以是Apache ShiroSpring Security。从成本和安全角度来看,这可能是一个很好的选择
  2. 维护单个模型而不是CQRS。这消除了一致性问题(如果您决定单独使用 用于存储模型的资源)。从我的理解 不应经常更改权限,但会访问它们 经常。这意味着您可以使用一个优化的模型 读取,避免一致性问题并维护2个模型。至 跟踪用户行为,您可以单独实施审计。 根据我的经验,安全审计可能需要额外的一些 很可能不在您的数据模型中的数据。
  3. 使用CQRS。在这里,我首先考虑重新审视要求,以找到接受eventual consistency而不是强一致性的方法。这为实施提供了许多选择。
  4. 关于这个问题,您是否应该使用引入专用的图形数据库,如果不了解您的域名,预算,所需的系统吞吐量和性能,现有的基础架构,团队知识和设置等,就无法回答。您需要通过专用来估算解决方案的成本图数据库,没有它。我的填充是,除非权限管理是您项目的主要想法,或者您的项目已经足够成熟(按用户数量和R& D容量),专用数据库不太可能为您的任务支付费用。

    要了解使用专用图形数据库可能带来的好处,您现有的存储解决方案应该采用相反的方式。这两篇文章很好地解释了这些好处: