Separate ES-related infrastructure code from application code
tjuerge opened this issue · comments
Currently the application code is entangled with the generic ES-related infrastructure code, e.g. the enums EventType
and AggregateType
are pulling-in domain-specific code into the generic EventRegistry
and AggregateRegistry
implementations.
For a simple example this is ok, but for a template of a production-grade application this could be improved - maybe by aligning to the architecture approach of Clean Architecture (as Tom Hombergs describes it in his blog post Hexagonal Architecture with Java and Spring and his book Get Your Hands Dirty on Clean Architecture ).
So I would like to suggest refactoring the ES-related infrastructure code from the application into it's own package or module.
Hi, Documentation is great. Is the code production-grade/ready?
Yes, the code is production-grade. For simplicity, there is only one Gradle module. In the real applications it may have sense to extract the event sourcing infrastructure code to the separate Gradle module or even project.
I plan to implement it soon. But it is more about project directory structure.
Thanks for the response.
event sourcing infrastructure code
You want to say that the generic code
relating to event-sourcing (which mainly constitute these folders: config, repository and service) should be placed in a separate directory, am I right?
The code placed in the projections directory
is domain-specific. Why have you decided not to make it generic. Is it because the projections are domain-dependent.. just like we can write different types of Queries for a given microservice/domain and therefore writing the generic code for the projection feature does not make sense?
For the event sourcing part there are quite a lot of generic code that can be reused by multiple domains if extracted into a separate Gradle module. Of course, there are also domain-specific code for event sourcing part (the concrete commands, events event handlers).
Projections doesn't require any generic code because they completely rely on Spring Data JPA. All we need for projections are Spring Data JPA repositories and JPA entities.
Source code files will be split between Gradle modules the following way:
Infrastructure code (generic code)
-
com/example/eventsourcing/config/
-
com/example/eventsourcing/domain/
-
com/example/eventsourcing/domain/command/
-
com/example/eventsourcing/domain/event/
-
com/example/eventsourcing/repository/
-
com/example/eventsourcing/service/
-
com/example/eventsourcing/service/command/
-
com/example/eventsourcing/service/event/
-
com/example/eventsourcing/error/
Application code (domain-specific code)
-
com/example/eventsourcing/config/
-
com/example/eventsourcing/domain/
-
com/example/eventsourcing/domain/command/
-
com/example/eventsourcing/domain/event/
-
com/example/eventsourcing/projection/
-
com/example/eventsourcing/repository/
-
com/example/eventsourcing/service/command/
-
com/example/eventsourcing/service/event/
-
com/example/eventsourcing/dto/
-
com/example/eventsourcing/mapper/
-
com/example/eventsourcing/controller/
@tjuerge , what do you think about splitting the code the way I described?
Great.. and thanks