Search code examples
asp.net-coredesign-patternsdomain-driven-designcqrsmediatr

Is AuthenticateUserQuery a valid Query in CQRS


Recently I have been trying to implement CQRS + DDD in my new ASP.NET Core project, as CQRS and DDD are very new to me, I read a lot of articles and examples online but could not get a deeper understanding.

Generic example:

I have the following:

Structure:

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

Or

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

I use Mediatr library to handle all my commands and queries.

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

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

Command: CreateUserCommand which takes in new user's UserId and Password and create a new User, then save it with Repository. Publish a UserCreatedEvent.

Now I want to create a function for clients to authenticate with UserId and Password. The function should have UserId and Password as input, and I will return UserAuthResult which has a bool field, true if UserId and Password is valid

I am thinking to create a AuthenticateUserQuery but I am not sure if it is actually a valid Query, or just a Domain Service.

The code flow of AuthenticateUserQuery would probably be:

  1. Controller send AuthenticateUserQuery to Mediatr
  2. Mediatr execute AuthenticateUserQueryHandler.Handle()
  3. AuthenticateUserQueryHandler get UserAuthDetailReadModel from UserAuthDetailReader
  4. Do authenticate with query's UserId + Password and UserAuthDetailReadModel
  5. Return UserAuthResult

Questions Time!

  1. From the description above, AuthenticateUserQuery only performs query/read, is it a valid Query or Domain Service
  2. If Question #1 is Query, is UserAuthResult a ReadModel? (Since it is returned from a Query)
  3. If Question #2 is a YES, is UserAuthDetailReadModel also a ReadModel? (Since it is NOT returned from Query, but return from Reader)
  4. If Question #1 is Query, does it mean as long as the Query only performs query/read with ReadModel, the name of Query does not limit to CRUD style of prefix (e.g. GetUserAuthDetailQuery)?
  5. If Question #1 is Domain Service, would you please give me some idea on how to implement it? (e.g. Class + Method signature)
  6. If Question #1 is neither, would you please give me some insight?

Appreciate any related suggestions and ideas. Thank you!


Solution

  • Authenticating a user has the nature of a command, not a query (you may not update any DB, but still you are asking to make some operation, authentication, on a user, not to query data for a user).

    Retrieving data (UserAuthDetailReadModel) as part of a use-case, as well as returning a success indication, does not make this use-case query.

    Having that said, you can infer that we are dealing here neither with a query nor with a domain service, but with a command: AuthenticateUserCommand.