CQRS. Should the team try to create a "complex" master-detail object?

I read the thoughts of Greg Young and Udi Dahan about the separation of the Query Responsibilty team, and a lot of what I read makes me feel like a chord. My domain (we track the vehicles that make deliveries) has a route concept that contains one or more stops. I need my clients to be able to install them in our system by calling the web service, and then they will receive information about the route and how the vehicle is moving.

In the past, I would have had “clipped” DTO classes that are very similar to my domain classes, and the client would create a RouteDto with an array of StopDto (s) and call our CreateRoute web method, passing it to RouteDto. When they query our system by calling the GetRouteDetails method, I would return the same objects to them. One of the attractive aspects of CQRS is that RouteDto can have all kinds of properties that the client wants to request, but does not have business parameters when creating a route. Therefore, I create a separate CreateRouteRequest class, which is passed when the CreateRoute command is called, and a route DTO class, which is returned as a result of the request.

class Route{ string Reference; List<Stop> Stops; } 

But I need my client to provide me information about the route and the stop when creating the route. As I see it, I could ...

Give my CreateRouteRequest class the Stops (s) property, which is an "something" array representing the data needed for each stop, but what do I call this class? This is not Stop, like what I call DTO inside my DTO route, but I don’t like "CreateStopRequest". I also wonder if I was stuck in CRUD thinking, thinking about the details of the master details and asking the client to think so too.

 class CreateRouteRequest{ string Reference; ... List<CreateStopRequest> Stops; } 

or

They call CreateRoute, and then make several calls to the AddStopToRoute method. This seems a little more "behavioral", but I will lose the ability to handle route creation, including its stops, as one atomic command. If they create a route and then try to add Stop, which does not work due to some verification problem, they will have a partially correct route.

The fact that I can’t find a good name for the list of StopCreationData objects that I will work with in option 1 makes me wonder if there is something that I don’t see.

+6
domain-driven-design cqrs
source share
3 answers

I understand that this is a really old post, but lately I have come across some similar patterns and feel the need to contribute to this topic. I think one thing that made OPs feel like they turned off was that they trained domain terminology in their own operational language, rather than matching their domain design.

The tip is off using "create" as a verb. “Create,” I found, is the same as “insert” in dev thinking (think “CRUD”), and we often resort to this verb when we first start to awaken DDD because it seems less technical. However, the routes created "here" already exist. They are simply written to the system. At the same time, stops on the route already exist, but are also recorded. A simple change in perception and wording, possibly with RecordRouteCommand, with the optional RecordStopOnRouteCommand companion collection, may have eliminated the confusion a bit. The ability to simultaneously send recording termination messages will also provide greater flexibility in building and enhancing the API.

I also agree with Szymon about the request against the team. This formulation also leads to a thought contrary to the cqrs approach. If there is one thing that DDD taught me, then the words that we use in our projects are not just important, they are of paramount importance.

+6
source share

I don’t think you are missing something.

 class CreateRouteRequest{ string Reference; ... List<CreateStopRequest> Stops; } 

It looks good to me. An alternative to using AddStopToRoute is, in my opinion, not a good idea, since it creates a too "chat" interface for efficient use remotely.

+4
source share

However, your use of the CreateRoute * * request indicates that you are using the Request / Response pattern.

If you really send commands to the server, the server should not return a Response object / message. You can simply offer your service the ExecuteCommand method and call it by passing the CreateRouteCommand command.

Request / response is not a valid CQRS IMHO.

+2
source share

All Articles