GithubHelp home page GithubHelp logo

Comments (21)

rganz avatar rganz commented on June 21, 2024 2

When I started with CQRS I struggled with the same "mismatch", what helped me is this:

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024 2

@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

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024 1

UpdateEntity Customer { id : 44465, active : false }

is very different than

DeactivateCustomer {id 44465 }

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024 1
> <account>
>     <account_number>12345</account_number>
>     <balance currency="usd">100.00</balance>
>     <link rel="deposit" href="/account/12345/deposit" />
>     <link rel="withdraw" href="/account/12345/withdraw" />
>     <link rel="transfer" href="/account/12345/transfer" />
>     <link rel="close" href="/account/12345/close" />
> </account>

as example. The handlers for the operations defined then are what actually creates the command internally.

from m-r.

MHacker9404 avatar MHacker9404 commented on June 21, 2024 1

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024 1

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)

from m-r.

bugproof avatar bugproof commented on June 21, 2024

@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.

from m-r.

bugproof avatar bugproof commented on June 21, 2024

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?

from m-r.

bugproof avatar bugproof commented on June 21, 2024

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 DeactivateUserCommand ?

void DeactivateUser(int userId) will be a command too right? even despite I don't have any input model named DeactivateUserCommand

or more general

void UpdateUser(User user) will be a command too right?

from m-r.

bugproof avatar bugproof commented on June 21, 2024

@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

void MakeCustomerPreferred(CustomerId)
void ChangeCustomerLocale(CustomerId, NewLocale)
void CreateCustomer(Customer)
void EditCustomerDetails(CustomerDetails)

CustomerReadService

Customer GetCustomer(CustomerId)
CustomerSet GetCustomersWithName(Name)
CustomerSet GetPreferredCustomers()

While for Task oriented UIs the definition for Command changes:

Commands
The method through which the Application Server will be told what to do is through the use of a
Command. A command is a simple object with a name of an operation and the data required to perform
that operation. Many think of Commands as being Serializable Method Calls. Listing 1 includes the code
of a basic command.

From: https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf

It seems like it applies differently in different usage contexts.

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024

The definitions for me are the same, how do you find them different?

from m-r.

bugproof avatar bugproof commented on June 21, 2024

@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:

public class DeactivateInventoryItemCommand {
 public readonly Guid InventoryItemId;
 public readononly string Comment;
 public DeactivateInventoryItemCommand (Guid id, string comment) {
 InventoryItemId = id;
 Comment = comment;
}

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.

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024

My slide for CQRS does not normally have reads going through the domain so I am a bit confused.

image

from m-r.

bugproof avatar bugproof commented on June 21, 2024

One definition says that

A command is a simple object with a name of an operation and the data required to perform that operation. Many think of Commands as being Serializable Method Calls. Listing 1 includes the code
of a basic command.

Other definition says that:

CQRS is a pattern that segregates the operations that read data (queries) from the operations that update data (commands) by using separate interfaces

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.

from m-r.

bugproof avatar bugproof commented on June 21, 2024

@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.

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024

Like what SimpleCQRS does? #TrollLOLLOL :P

https://github.com/gregoryyoung/m-r/blob/master/SimpleCQRS/Commands.cs

from m-r.

bugproof avatar bugproof commented on June 21, 2024

@gregoryyoung Can't this duplication be a bit simplified?

public class CheckInItemsToInventory : Command {
public Guid InventoryItemId;
public readonly int Count;
public readonly int OriginalVersion;

public class RemoveItemsFromInventory : Command {
public Guid InventoryItemId;
public readonly int Count;
public readonly int OriginalVersion;

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024

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 ;-)

from m-r.

bugproof avatar bugproof commented on June 21, 2024

@gregoryyoung I have CRUD based UI does it make sense to apply CQRS?

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024

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.

from m-r.

gregoryyoung avatar gregoryyoung commented on June 21, 2024

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

from m-r.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.