所以我喜欢在我们的应用程序中使用CQRS的概念,主要是因为我们已经支持事件采购(概念上,不遵循您在那里看到的任何处方)。然而,看起来CQRS似乎是面向大数据,最终的一致性,那种事情。我们总是成为一个关系数据库应用程序,所以我不确定它是否合适。
我也有顾虑,因为我认为我需要在我的应用层中做一些特殊的事情。在进行读取时,我需要强制执行安全性和过滤数据,这些是传统上在应用程序层中实现的内容。
我的第一个问题是,我的应用程序是否合适(传统的MVC /关系数据库应用程序)?或者使用传统的应用层并使用DTO Mapper更有意义吗?
我的第二个问题是,从传统的应用程序层向域模型发出命令是否有意义?我喜欢命令/命令处理程序和事件的想法。
让我澄清一下我的问题。我担心与授权相关的数据过滤。当用户请求数据时,必须有一个过滤器,通过将它们全部一起删除(因此它们不会返回给调用者),隐藏值或对数据应用掩码来限制对某些数据元素的访问。在一个人为的例子中,对于社会安全号码,提出请求的用户可能只能看到最后4个号码,因此结果看起来像### - ## - 1234。
我的断言是这个责任在应用层中。我认为这是一个方面,其中对查询或命令的所有响应都必须通过此过滤器机制。这是我的CQRS天真的地方,也许是命令永远不会返回数据,只是指向通过读取模型查找的数据的指针?
谢谢!
答案 0 :(得分:9)
首先: CQRS 和关系数据库不要相互排斥。在高级方案中,将基于SQL的DB替换为其他存储方式可能是有意义的,但CQRS作为一个概念并不关心持久性机制。
如果多个视图依赖于角色和/或用户,精简读取层应该可能提供多个结果集:
这些可以存储在单独的数据存储中,但如果使用单个基于SQL的数据库,也可以通过SQL视图提供它们。
在CQRS中,应用程序服务仍然以命令处理程序的形式存在。这些可以嵌套,即首先处理授权,然后将命令发布到包含的命令处理程序。
public class AuthorizationHandler {
public CrmAuthorizationService(CrmCommandHandler handler) {
_next = handler;
}
public void Handle(SomeCommand c) {
if (authorized) _next.Handle(c);
}
}
// Usage:
var handler = new CrmAuthorizationService(new CrmCommandHandler());
bus.Register<SomeCommand>(handler.Handle);
这样你可以嵌套多个处理程序,例如作为 REST信封,用于记录,事务等。
回答您的问题:
首先: CQRS是否适合您的应用?没有人真正深入了解具体要求就无法分辨。仅仅因为你使用MVC和关系数据库在CQRS的优缺点方面没有任何意义。
第二:是的,在某些情况下,让您的应用层以经典方式与客户端交互并处理身份验证,授权等内容,然后在内部发出命令是有意义的。在将基于MVC的UI或REST API放在应用程序之上时,这非常有用。
更新以回复评论:
在理想的,纯粹的CQRS场景中,Sally会为每个视图提供自己的非规范化数据,例如: NoSQL DB中的一些文档名为 CustomerListForSally , CustomerDetailsForSally 等。这些文档中包含了她允许查看的内容。
一旦她获得晋升 - 这将是一个重要的领域事件 - 所有她的非规范化数据将被自动覆盖,并扩展到包含她现在允许看到的内容。
当然,我们必须保持合理和务实,但这个理想应该是我们前进的大方向。
实际上,您可能拥有某种用户/角色或基于用户/组的系统。为了能够查看敏感信息,您必须是特定角色或组的成员。这些中的每一个都可以具有其定义的视图和命令集。这不需要被解压缩数据它可以像SQL-Views一样简单: