Reputation: 2876
I'm starting to learn EventSourcing with a DDD perspective. One claim about EventSourcing is that it allows to replay the state of the application by replaying the events or even put the application in a state it was before (past state).
I'm realising the complexity it adds and the benefits it has over other solutions. What I am really concerned about is where the generation of events occurs. Front-end or back-end?
I'll explain it with an example.
Imagine that my application, which is comprised of frontend and backend is about users. The user representation could be as follows (I'll be using JSON for representations although the question is not format nor language specific):
{
id: int,
name: string,
age: int,
description: string
}
First question:
Imagine that I create a user from the frontend. My server receives the following:
{
id: 1,
name: "aName",
age: 20,
description: "aDescription"
}
Should the following events be emitted? CreatedEvent, NameChangedEvent, AgeChangedEvent, DescriptionChangedEvent
In this case, the events generated in the frontend (just one), are not the same as the ones generated in the backend (four).
Or instead a CreatedEvent with all proprerties should be emitted? In this case, the events in the the backend resemble de front end ones (just one)
A similar problem happens when an update is performed. If I change several proprierties at once from the frontend, should I create one event in the backend with all those changes or should I split those changes in multiple events? If I have to split those changes in multiple events I will have to check the current state of the entity (user) to check whether the proprety has changed or not.
Upvotes: 2
Views: 466
Reputation: 57257
What I am really concerned about is where the generation of events occurs. Front-end or back-end?
The answer depends on where the book of record is. If truth is determined by the service itself, then the book of record is the persistent store of the service -- in these cases, the events are usually generated in the back-end.
If truth is determined outside of the service boundary (in another service, or in the real world), then the events are usually generated closer to the source of truth.
If we're doing data entry, we are probably describing something in the real world, rather than something controlled by the model. That sounds like a front end use case to me.
Imagine that I create a user from the frontend
CRUD verbs are a code smell -- they usually indicate a shallow understanding of the domain, or an attempt by coders to replace the domain specific language with a generic one.
Sometimes they are a hint that you are really building a database, rather than a service, which is one of the hints that your service isn't the book of record, but is instead merely a durable store. So again, this spelling suggests that the front end is capturing events, and passing them to the back end.
You may want to be careful in your spelling of names here, in so far as you are often working with snapshots of entities that are in the middle of their life cycle (ex: the "user" has been around for 20 years, but we are only capturing their current state, not their entire history).
Should the following events be emitted? CreatedEvent, NameChangedEvent, AgeChangedEvent, DescriptionChangedEvent
Not in general, no. Changes are normally represented atomically.
A similar problem happens when an update is performed. If I change several proprierties at once from the frontend, should I create one event in the backend with all those changes or should I split those changes in multiple events?
See Task Based UI. Edits don't usually come from nowhere, but usually have a cause that may be of interest to the business (are we correcting an incorrect entry? Did the real world change, invalidating our previous data?). It's perfectly reasonable to have multiple events that include changes to the same set of fields.
Upvotes: 2
Reputation: 17683
You are still thinking in CRUD
. In CQRS
you don't set properties, you execute Commands
. Those Commands
have a meaning to your domain model; they are sent to the Aggregates
that verify and execute them if the invariants hold; if not, they are rejected.
I'm realising the complexity it adds and the benefits it has over other solutions. What I am really concerned about is where the generation of events occurs. Front-end or back-end?
The events are generated by the Aggregate, and probably the Aggregate is executed in the back-end. The front-end may create only a command that is sent to the back-end.
Should the following events be emitted? CreatedEvent, NameChangedEvent, AgeChangedEvent, DescriptionChangedEvent
What events should be emitted depends on your invariants. In your specific case, it is permitted by the business rules that a User
is born without a name
, age
or description
? If not, then you must put in the CreateUserCommand
all the required fields and possibly the optional ones and emit a complete UserWasCreated(id, username, age, description)
. But it is not forbidden to emit multiple events as long as they are persisted in a transaction-like manner (it is not required to use transactions, it is required that the persist is atomic: all the events are persisted or none). Should you emit one big event or four? It depends on how it feels right for the listeners of those events as it is irrelevant for the Aggregate: the Aggregate will receive what it emits and it will be sufficient to rebuild its internal state.
How granular the events are generated may depend if you permit a granular command like ChangeUserName
; if you permit such a command then this command would emit the UserNameChanged
event.
Upvotes: 3