I'm implementing a project using CQRS and Event Sourcing. I realized that my commands and my events are nearly always the same.
Let's say I have a command CreatePost
:
public class CreatePost implements Command {
private final String title;
private final String content;
}
The event fired from this command is the same :
public class PostCreated implements Event {
private final String title;
private final String content;
}
How do you handle that in your applications ?
EDIT : Of course I'm aware of basic OOP technics. I could create an abstraction having the common fields, but this question needs to be taken in the CQRS/ES context.
How to avoid repeating fields between command and event?
I wouldn't -- not until I absolutely can't stand it.
Fundamentally, commands and events aren't objects, they are messages - representations of state that cross boundaries. I think it's important that your in memory representation not lose sight of that.
One of the characteristics of message schemas is that they evolve over time, so you need to be aware of compatibility. And here's the kicker: events and commands evolve on different time scales.
Command messages are how your domain model communicates with other processes; changes to that part of the API are driven by exposing/deprecating functionality.
But in an event sourced world, events are messages from previous versions of the domain to the current version. They are part of the support we need to deploy new models that resume work from where the old model left off.
So I would keep commands and events separate from one another - they are different things.
If you are seeing a lot of duplication in the fields, that may be a hint that there's some value type that you haven't yet made explicit.
CreatePost
{ Post
{ Title
, Contents
}
}
PostCreated
{ Post
{ Title
, Contents
}
}
Simply implement a model for your Post
, i.e.:
public class PostModel {
private String title;
private String content;
// Add get/set methods
}
Then re-use this in both your events and commands.
Just compiling this answer from the discussion we had in comments.
I would definitely not use inheritance in a situation like this because it will just add unnecessary complexity, also there is no behavior to inherit there.
Another option is to have a well-defined contract for your commands and events. That is to have two interfaces — IPost
and IEvent
— and implement those in the commands and events.
Regarding naming: we all know that naming is hard, so you should choose names wisely, according to your business or technical language/vocabulary requirements.
Because a command usually carries more information required for its handler than an event carries for its event handler, event handlers should be kept as thin as possible. It's better to carry only the needed payload.
Separating commands and events is a must, since commands are representing an operation that's happening now, whereas events are representing actions that happened in the past. They might usually be an outcome of a command, indicating to the outside world — from the viewpoint of a bounded context — that something happened inside your current BC.
How to avoid repeating fields between command and event?
Just don't. The cost of dependency + risk of wrongful mutualization are higher than the maintenance gain. You can live with that duplication, just like you probably live with duplication between your domain model, view model, query model, etc. today.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With