Comments (8)
Sounds like we're in line to a large degree. I guess that for your global events you could got with jMolecules @DomainEvent
as they're likely to be picked up by downstream tools for documentation.
I like the suggestion to move to @ReadModel
over @ViewModel
for exactly the arguments brought up.
from jmolecules.
Almost forgot the last one: Query / Query Handler.
I think it's important to include these. While Axon is quite opinionated and suggests using explicit Query objects, I think the concepts are more generally beneficial. A QueryHandler doesn't have to be a handler for these explicit query objects. It could simply mark an endpoint that is used to expose the query model to other components. Whether that's through explicit message objects (themselves marked with @Query
), or just an HTTP endpoint, is irrelevant.
Maybe just a fun fact, but explicit Query objects have only been added relatively recently to Axon Framework. I didn't see the need for them for a long time. It is under "community pressure" that we decided to add the QueryBus and Query Messages. And I have to admit: they were right!
from jmolecules.
Just a few thoughts on this:
-
The developer wouldn't pull
jddd-architecture
into the project, but ratherjddd-architecture-layered
or, as with cqrs,jddd-achitecture-cqrs
. So IMHO it'd be fine from this perspective. As implementing CQRS or ES in the system is an architectural decision and it has a direct effect on the implementation, putting it intojddd-architecture
looks at least to me not wrong. One could argue that then also the core DDD annotations should be insidejddd-architecture
. However, using CQRS and ES are additions when using DDD (could even be used without DDD), the same holds for the technical architecture style. I'd like to raise the question whetherjddd
is still the correct base when we start introducing additional patterns, since it suggests a string DDD focus. -
We should stay consistent and thus I prefer
@DomainEventHandler
. -
'@viewmodel' also for me
from jmolecules.
The developer wouldn't pull jddd-architecture into the project, but rather jddd-architecture-layered or, as with cqrs, jddd-achitecture-cqrs. So IMHO it'd be fine from this perspective. As implementing CQRS or ES in the system is an architectural decision and it has a direct effect on the implementation, putting it into jddd-architecture looks at least to me not wrong. One could argue that then also the core DDD annotations should be inside jddd-architecture. However, using CQRS and ES are additions when using DDD (could even be used without DDD), the same holds for the technical architecture style. I'd like to raise the question whether jddd is still the correct base when we start introducing additional patterns, since it suggests a string DDD focus.
Good points. I'll try to approach them one by one:
- The artifact naming discussion – I oversaw that we're planning with artifacts by architectural style. A
jddd-architecture-cqrs
would thus fit nicely. - Is CQRS / ES an "architecture" – I think the CQRS part pretty clearly is as it has implications on the overall structure of the codebase, kind of splitting it into two different worlds. For the ES part, I'm not so sure as it's essentially an implementation strategy for repositories: "We reestablish state based on the reapplication of events we have stored". I.e. a repository client shouldn't necessarily have to know about it being implemented via ES or destructive persistence.
- The architecture artifact arrangement in general – I've seen the 'architecture' artifacts as "Stereotypes that help describing architectures commonly used in DDD context". While I agree that you can use those architectures without doing DDD, that is sort of expressed by the fact that these artifacts do not depend on
jddd-core
. I think it's fine to then ask whether these annotations should be part of either this project or something namedjddd
in the first place but it feels like that's getting into very detailed discussion, esp. as the project already is nothing more than an implementation of commonly used patterns in code. Happy to think about a rename / restructuring at some point, but I would like to get more feedback on whether the core idea ("Does a meta model separated from frameworks?") provide real benefit to both users and framework implementors first.
In summary, I wonder if a slightly different arrangement of annotations and artifacts makes sense and matches the observations a bit better:
- Add
@DomainEventHandler
tojddd-events
instead of the artifact. It would colocate everything related to handling events in the artifact designed to contain those. Would@ViewModel
go here then as well? It nudges thejddd-events
artifact towards event source quite a bit but at the same time it feels a bit overly complex to introduce a separate artifact just for that. - Let the CQRS architecture artifact contain all command and query annotations (do we actually want to add the latter in the first pass?).
@DomainEventHandler
👍
@ViewModel
👍
from jmolecules.
As I build a CQRS based system I just would like to share which building blocks we use. The naming evolved incrementally over months as we refactored constantly.
This is the current state:
Command - The command itself
CommandHandler - The component handling a given command
Local event - Events which are not supposed to be propagated to the outside world. They are used for EventSourcing an Aggregate.
Global event - Propagated to the outside world. "Domain event" might be more appropriate.
Event Handler - The component handling events
Projection - That's the term we refactored most often. It started with Read Model and ended it with Projection. We don't use ViewModel because the term is linked to the UI world closely. A projection can feed an UI, but it doesn't have to. We use projections a lot to build views on data which is exposed by other bounded context in order to decouple the BCs.
Projector - A projector is responsible for performing CRUD operations against the projection. It's more or less an Event Handler. As it handles all the events which are relevant for keeping the projection up to date.
We also use Queries and Query handlers, but most of the time we don't need them. Querying the projection repository is fine without having a dedicated building block.
Hope this helps...
from jmolecules.
@abuijze and team – I wouldn't mind your feed back on this and what's been suggested in #39 to make sure we're not fundamentally at odds with what you have in Axxon. Of course, still assuming that developers might want/need to fall back onto Axxon specific annotations for more advanced use case. I hate to bring up this comparison but see this here as the "JPA" compared to "Hibernate" of CQRS / ES building block definitions. 😉
from jmolecules.
Hi @odrotbohm and others here. Sorry for being late to the game.
Actually, the JPA/Hibernate comparison isn't too far off. I have been discussing different forms of standardization already with other suppliers of "CQRS tooling", but those discussions were too much into defining what frameworks must do, instead of stereotyping components, like this module seems to focus on.
I agree with many of the conclusions taken here. Just for completeness, here my 2ct on them:
- Artifact naming -> don't have too strong an opinion on this one. CQRS is often referred to as an architectural style, rather than an architecture, but I don't think that is relevant for the naming discussion. If one intends to use CQRS as a "component" in an application's architecture, it makes sense to include a
jddd-architecture-cqrs
module to annotate the relevant components. - ViewModel/Projection/ReadModel -> my preference goes strongly to ReadModel, or alternatively QueryModel. ViewModel implies that it's used to feed a View, which in turn implies that an external actor is using this for information. That doesn't need to be the case. Projection implies that is has been projected from a (generally) stream of information. Strictly speaking in CQRS, this also doesn't need to be the case. ReadModel implies that the model is focused on Reading, which seems the most accurate. However, CQRS is not called Write-Read Responsibility Segregation. Therefore, I believe QueryModel is even more accurate.
- DomainEvent/Event and DomainEventHandler/EventHandler -> Event can mean many things. I agree with using DomainEvent for this. Regarding (Domain)EventHandler, while consistency is important, I'm not too sure about naming it DomainEventHandler. An Event Handler can handle Events, whether they are considered Domain Events, Application Events, or System Events. While I've seen the latter pop up more in discussions than in real code bases, Application Events are very common (Spring uses them to notify applications of the ApplicationContext lifecycle changes, for example). Some Projectors may want to use these Events too in their logic. My vote would go for EventHandler.
I just wanted to provide a little context here before I dive into the PR (#39) that's already open for this.
from jmolecules.
That's available now.
from jmolecules.
Related Issues (20)
- `ValueObject` interface for KMolecules HOT 7
- Release 1.9
- Upgrade to Kotlin 1.8.22
- Upgrade to JUnit 5.10
- Upgrade to AssertJ 3.24.2
- Nesting of multiple Entities / AggregateRoots? HOT 1
- Code typo in README.md file HOT 2
- Update copyright headers
- Somewhat lacking documentation
- Introduce support for @QueryHandler, @QueryDispatcher and @Query
- Release 1.6
- Add jmolecules-hexagonal-architecture to bom HOT 1
- How to use the package annotations in Kotlin? HOT 2
- Bound of `T` for `ddd.types.Entity<T, ID>` is wrong? HOT 1
- Consistency in CQRS architecture package names
- Release 1.7
- Add Clean Architecture to architectures HOT 6
- `@Identity` annotation is missing in `kmolecules-ddd` HOT 3
- Add support to qualify domain events as to-be-externalized
- Release 1.8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jmolecules.