Validation CQR中的验证是否必须分别在UI和业务域中进行一次?
我最近读了这篇文章,仍在努力了解CQR 我不确定输入验证应该在哪里进行,以及是否可能必须在两个不同的位置进行(从而违反了“不要重复自己”规则,也可能会分离关注点) 给定以下应用程序架构:Validation CQR中的验证是否必须分别在UI和业务域中进行一次?,validation,dry,separation-of-concerns,cqrs,Validation,Dry,Separation Of Concerns,Cqrs,我最近读了这篇文章,仍在努力了解CQR 我不确定输入验证应该在哪里进行,以及是否可能必须在两个不同的位置进行(从而违反了“不要重复自己”规则,也可能会分离关注点) 给定以下应用程序架构: # +--------------------+ || # | event store | || # +--------------------+ || # ^ |
# +--------------------+ ||
# | event store | ||
# +--------------------+ ||
# ^ | ||
# | events | ||
# | v
# +--------------------+ events +--------------------+
# | domain/ | ---------------------> | (denormalized) |
# | business objects | | query repository |
# +--------------------+ || +--------------------+
# ^ ^ ^ ^ ^ || |
# | | | | | || |
# +--------------------+ || |
# | command bus | || |
# +--------------------+ || |
# ^ |
# | +------------------+ |
# +------------ | user interface | <-----------+
# commands +------------------+ UI form data
#+-------------+||
#|活动商店|||
# +--------------------+ ||
# ^ | ||
#|事件|||
#|v
#+-------------+事件+--------------------+
#|域/|---------------------->|(非规范化)|
#|业务对象| |查询存储库|
# +--------------------+ || +--------------------+
# ^ ^ ^ ^ ^ || |
# | | | | | || |
# +--------------------+ || |
#|命令总线| | ||
# +--------------------+ || |
# ^ |
# | +------------------+ |
#+--------------用户界面|我想我的问题已经被另一篇文章Udi Dahan解决了。“命令和验证”一节的开头如下:
命令和验证
在思考什么可能导致命令失败时,出现的一个主题是验证。验证是
与业务规则不同的是,它声明了与上下文无关的命令事实。要么是
命令是否有效。另一方面,业务规则依赖于上下文
[…]即使命令可能有效,也可能有拒绝它的理由
因此,可以在客户端上执行验证,检查该命令所需的所有字段
有吗,号码和日期范围都可以,诸如此类。服务器仍将验证所有
到达的命令,不信任客户端进行验证
我认为这意味着——考虑到我有一个基于任务的UI,正如经常建议的那样,CQR可以很好地工作(命令作为域动词)——如果由于命令所需的某些数据仍然丢失或无效而无法发送命令,我只会灰显(禁用)按钮或菜单项;UI对命令本身的有效性作出反应,而不是对命令对域对象的未来影响作出反应
因此,不需要CanDoX命令,也不需要将域验证逻辑泄漏到UI中。但是,UI将具有一些用于命令验证的逻辑。客户端验证基本上限于格式验证,因为客户端无法知道服务器上数据模型的状态。现在有效的,可能在1/2秒后无效
因此,客户端应该只检查是否填写了所有必需的字段,以及它们的格式是否正确(电子邮件地址字段必须包含有效的电子邮件地址,例如,.+)@(.+)(.+)等等)
所有这些验证以及业务规则验证都将在命令服务中的域模型上执行。因此,在客户端上验证的数据仍可能导致服务器上的命令无效。在这种情况下,一些反馈应该能够返回到客户端应用程序。。。但那是另一回事。我从ASP.NET MVC的角度处理CQR(无论好坏),我的控制器(创建和发出命令)实际上只执行最少的操作。验证从客户端发送的输入,以确定是否应发出命令,并准备视图。我的业务逻辑包含在我的域中,不会泄漏到UI。我想你在这里的方向是对的。祝你好运但我认为您可能仍然需要CanDoX查询,以便灰显UI中的某些命令。CanDoX可能由专门为查询端设计的授权服务/层使用。CanDoX听起来像是查看内容的授权检查。CanDoX==IsAuthorizedToDoX(CanViewX/IsAuthorizedToViewX)。命令端的大部分CanDoX应该在模型本身中设计。用户可以是作者吗?一本书可以由作者来修改吗?这些都是普遍存在的问题的一部分language@Tudor当前位置你知道英国喜剧小品里解释了“可以”和“可以”的区别吗?其中一条相关的引语是:(链接不会转到草图,因为我再也找不到它了。:-@stakx:)是的,“may”是一个更好的词,用于描述用户应该被允许做什么。感谢您回答并确认我达成的理解。一开始我没有意识到,根据域的当前状态验证命令和验证命令本身是有区别的。我完全忽略了后一点,认为两者是同一件事,发生在同一领域;现在我很清楚,只有前一个验证步骤发生在域中;只有后者通过禁用命令按钮等方式反映在UI中。我想听听Feedback是如何回到客户端的(电子邮件故事除外)