-
Notifications
You must be signed in to change notification settings - Fork 529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CQRS and CRUD misconception #28
Comments
UpdateEntity Customer { id : 44465, active : false } is very different than DeactivateCustomer {id 44465 } |
@gregoryyoung but when you create REST API it always looks like the first example. Does it mean CQRS doesn't make sense when implementing REST API? I mean technically it can be done by creating something like UpdateCustomerCommand and using it to deactivate customer using your first example. |
as example. The handlers for the operations defined then are what actually creates the command internally. |
Oh, I get it now. But does it mean CQRS can't be used with CRUD? (means no operations, just passing the state/object) For example, closing the account would be setting isClosed to true. Does using it in this context make sense? |
You can still use CQRS with CRUD...Just need better definition on the Command vs Query objects being used. Think Single Responsibility or Interface Segregation - an update command to change active status does not offer the same clarity of definition as a DeactivateUserCommand object.
…________________________________
From: lecoque <notifications@github.com>
Sent: Monday, June 18, 2018 08:00
To: gregoryyoung/m-r
Cc: Subscribed
Subject: Re: [gregoryyoung/m-r] CQRS and CRUD misconception (#28)
Oh, I get it now. But does it mean CQRS can't be used with CRUD?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub<#28 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AD_ZHEMj9LD2AgExmk2haJiPYL_pURkQks5t95ZWgaJpZM4UrlrM>.
|
CQRS/CQS doesn't say anything about the single responsibility of a command. It tells to just isolate write methods from read methods. Does it mean I don't need command-specific objects like
or more general
|
When I started with CQRS I struggled with the same "mismatch", what helped me is this:
|
@rganz at first I thought that was to me and was going to be forced to point out the irony that I wrote the first article :P |
@rganz Yeah there's a confusion when talking about CQRS in Task-oriented UIs vs CRUD oriented UIs. The definition of the pattern looks different for both. For example, the definition for CRUD oriented UIs presents CQRS as: CustomerWriteService
CustomerReadService
While for Task oriented UIs the definition for Command changes:
From: https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf It seems like it applies differently in different usage contexts. |
The definitions for me are the same, how do you find them different? |
@gregoryyoung There are no "SomeActionCommand" classes in your example of CQRS with CustomerWriteService and CustomerReadService and original definition describes commands as operations not data models/structures of data. The definition says just to segregate methods that read from those that write and you're done. But later in "Task based user interfaces" section it introduces new definition of command. Giving examples like:
Does it mean there is a different definition of Command in CQRS depending on usage? There is no clear definition of what command really is, first it says just to use different interfaces and you're done and then all of sudden it talks of commands as of data structures where you define some data to pass to perform some action. |
One definition says that
Other definition says that:
One definition speaks of a command as of a "simple object". The second definition speaks of a command as operation that update data. The original definition of CQS talks about commands as of methods, not objects. |
CQRS can be applied to methods or messages. To be fair the difference is rather not worth discussing as some languages use messages to implement method calls :) refactor method to message is widely available (refactor parameters to object) |
@gregoryyoung I think it's worth discussing because "Command" gets a different meaning when applied to messages if by that you mean event-driven systems that handle things after receiving some message. To make more sense it would be nice to provide example like: class MakeCustomerPreferredCommand
{
public int CustomerId { get; set; }
}
class CreateCustomerCommand
{
public Customer Customer { get; set; }
}
class EditCustomerDetailsCommand
{
public CustomerDetails CustomerDetails { get; set; }
} That presents commands as objects instead of methods/operations. |
Like what SimpleCQRS does? #TrollLOLLOL :P https://github.com/gregoryyoung/m-r/blob/master/SimpleCQRS/Commands.cs |
@gregoryyoung Can't this duplication be a bit simplified? Lines 43 to 46 in 31d315f
Lines 55 to 58 in 31d315f
|
Could be but you probably don't want to. They are defining schema. What happens when you have 3 levels of inheritance etc and need to change something higher up? How much time did you save through you reuse? Its frankly also a PITA to go searching through inheritance hierarchies. There are as well tools that generate this stuff for you ;-) |
@gregoryyoung I have CRUD based UI does it make sense to apply CQRS? |
Not usually though it can. Normally you are more interested in behaviours, why something happens is often important. If you just need CRUD why not just maintain a SQL transaction file? To be clear "Volume changed" on our order in the stock market. Why did volume change? We could have changed it, the market could have changed it (varying rules etc), it could have traded, it could be a regulatory cancellation, etc. if you don't have the separate events I bet you get a bunch of code figuring out which type it was in many places. |
That was my original point. Often no. I have discussed this a lot in talks there are simpler ways of reaching the same goal such as an audit table on updates. I am not trying to put you off the idea (it has benefits) but often they will not be realized IME |
There are many articles and videos like "CQRS vs CRUD". They're not even the same things. Because you can use CQRS with CRUD (for example, CreateCommand, UpdateCommand, DeleteCommand) and mostly all applications are CRUD. Can you clarify?
Is implementing CRUD using CQRS misusing CQRS?
Is CQRS suitable for implementing REST/resource-based APIs with CRUD mental model, or it's a better fit for RPC APIs?
How do you use CQRS with DDD, how do you map to domain models? Do you map directly from your commands to domain models? Or do you use commands just as DTO holders? see https://stackoverflow.com/questions/50908260/cqrs-with-mediatr-and-re-usability-of-commands
The text was updated successfully, but these errors were encountered: