AuthenticateUserQuery 是 CQRS 中的有效查询吗

Is AuthenticateUserQuery a valid Query in CQRS

最近我一直在尝试在我的新ASP.NET核心项目中实现CQRS + DDD,因为CQRS和DDD对我来说很新,我在网上看了很多文章和例子,但没有得到一个更深入的理解。

一般示例:

我有以下内容:

结构:

Front-End <==> Controller <==> Mediatr <==> Command Handler <==> Repository

Front-End <==> Controller <==> Mediatr <==> Query Handler <==> Reader

我使用 Mediatr 库来处理我所有的命令和查询。

Repository returns/save Aggregate Root/Domain/WriteModel, Reader returns ReadModel.

聚合Root/Domain/WriteModel: class User { string UserId , string Password }

命令: CreateUserCommand 接受新用户的 UserIdPassword 并创建一个新的 User,然后用 Repository 保存它。发表一篇UserCreatedEvent.

现在我想为客户端创建一个函数以使用 UserIdPassword 进行身份验证。该函数应该有 UserIdPassword 作为输入,我将 return UserAuthResult 有一个 bool 字段,如果 UserIdPassword 有效

我正在考虑创建一个 AuthenticateUserQuery,但我不确定它是否真的有效 Query,或者只是一个 Domain Service.

AuthenticateUserQuery的代码流程可能是:

  1. Controller 发送 AuthenticateUserQueryMediatr
  2. Mediatr执行AuthenticateUserQueryHandler.Handle()
  3. AuthenticateUserQueryHandlerUserAuthDetailReader
  4. 得到 UserAuthDetailReadModel
  5. 使用查询的 UserId + PasswordUserAuthDetailReadModel
  6. 进行身份验证
  7. ReturnUserAuthResult

提问时间!

  1. 从上面的描述,AuthenticateUserQuery只执行query/read,是有效的Query还是Domain Service
  2. 如果问题 #1 是 QueryUserAuthResultReadModel 吗? (因为它是 return 编辑自 Query
  3. 如果问题 #2 是肯定的,那么 UserAuthDetailReadModel 也是 ReadModel 吗? (因为它不是 return 来自 Query,而是 return 来自 Reader
  4. 如果问题 #1 是 Query,是否意味着只要 Query 只执行 query/read 和 ReadModelQuery 的名称不限于 CRUD 前缀样式(例如 GetUserAuthDetailQuery)?
  5. 如果问题 #1 是 Domain Service,您能给我一些实现方法吗? (例如 Class + 方法签名)
  6. 如果问题 #1 都不是,请您给我一些见解好吗?

感谢任何相关的建议和想法。谢谢!

验证用户具有命令的性质,而不是查询(您可能不会更新任何数据库,但您仍然要求对用户进行一些操作、验证,而不是为用户查询数据) .

检索数据 (UserAuthDetailReadModel) 作为用例的一部分,以及返回成功指示,不会进行此用例查询。

话虽如此,您可以推断我们在这里处理的既不是查询也不是域服务,而是命令:AuthenticateUserCommand。

没有理由让事情变得更复杂。

CQRS 的词汇来自 Bertrand Meyer's concept of Command Query Separation (CQS)。区别真的不难。

  • 一个命令是一个有副作用的操作,但是return没有数据。
  • 查询是对 return 数据的操作,但没有副作用。

CQRS 详细阐述了定义架构风格的想法,但定义仍然存在。

CQS 规定任何操作必须是或者一个命令或者一个查询;在那个术语中不能两者兼而有之。这个概念也适用于 CQRS。

在 C# 和 Java 等主流静态类型语言中,命令很容易识别。由于命令被禁止 returning 数据,它 必须 具有 return 类型 void.

通过排除,那么,如果你遵循CQS,具有return类型的方法必须是查询。

既然你的验证操作return是一个结果,那么它不能是一个命令。

从技术上讲,C# 或 Java 等语言不强制执行 CQS,但如果您可以说服自己身份验证操作没有副作用(我不希望它有),那么它必须是查询。