After getting the first version of #Java samples of #EventSourcing, I asked the community for feedback for my PR
https://github.com/oskardudycz/EventSourcing.JVM/pull/1
I">https://github.com/oskardudy... wanted to get harsh but fair feedback to make it idiomatic and, in general, better. I got what I ask for, let me share what I learned
https://abs.twimg.com/emoji/v2/... draggable="false" alt="👇" title="Rug van hand met omlaag wijzende wijsvinger" aria-label="Emoji: Rug van hand met omlaag wijzende wijsvinger">
https://abs.twimg.com/emoji/v2/... draggable="false" alt="😅" title="Lachend gezicht met open mond en angstzweet" aria-label="Emoji: Lachend gezicht met open mond en angstzweet"> 1/
https://github.com/oskardudycz/EventSourcing.JVM/pull/1
I">https://github.com/oskardudy... wanted to get harsh but fair feedback to make it idiomatic and, in general, better. I got what I ask for, let me share what I learned
Java Optional should be used only as a result, to reduce the confusion around the `void` type. It should not be used as a method input parameter or field. This makes sense, as Java generics are more compile-time templates and are zipped. See more in: https://nipafx.dev/design-java-optional/">https://nipafx.dev/design-ja... /2
I already used sealed interfaces to have a nice pattern matching while rebuilding the state from events. Yet it appeared that they allow full "union types" experience! After that, I went further and created
https://abs.twimg.com/emoji/v2/... draggable="false" alt="👇" title="Rug van hand met omlaag wijzende wijsvinger" aria-label="Emoji: Rug van hand met omlaag wijzende wijsvinger">It enables concise and precise modelling /3 https://twitter.com/oskar_at_net/status/1506998215714955268">https://twitter.com/oskar_at_...
I& #39;m a huge fan of slicing architecture vertically ( https://event-driven.io/en/how_to_slice_the_codebase_effectively/).">https://event-driven.io/en/how_to... I also think that composition = simplicity. Yet, "simple" means different for everyone. Sometimes is better to group smaller things to provide more accessible structure like https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/main/java/io/eventdriven/ecommerce/shoppingcarts/ShoppingCartService.java">https://github.com/oskardudy... /4
Spring Boot has a built-in ApplicationEventPublisher ( https://reflectoring.io/spring-boot-application-events-explained/),">https://reflectoring.io/spring-bo... so there& #39;s no need to implement a custom in-memory bus. I had to go full-circle and remove my "great" but totally redundant implementation. Reminder: not forget to learn tools, before going custom /5
Pushing up all the possible exceptions is like being sainter than the pope. If we don& #39;t want to handle them in code, then it& #39;s better just to make them runtime exceptions and catch them in a generic mechanism. Read more about checked/unchecked split /6 https://baeldung-cn.com/java-checked-unchecked-exceptions">https://baeldung-cn.com/java-chec...
Btw. for the global exception handling, you can use ControllerAdvice and ExceptionHandler annotation like that
https://abs.twimg.com/emoji/v2/... draggable="false" alt="👇" title="Rug van hand met omlaag wijzende wijsvinger" aria-label="Emoji: Rug van hand met omlaag wijzende wijsvinger">This enables doing an automated mapping to HTTP Statuses /7 https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/main/java/io/eventdriven/ecommerce/core/http/GlobalExceptionHandler.java">https://github.com/oskardudy...
As I& #39;m not a huge fan of annotations/attributes/decorators with conventional-based magic, I decided to do manual Java Beans registrations. I stand by my decision, but I think that I went too far. It& #39;s better to compose stateless code rather than outsourcing it to DI /8
Reviewers also motivated me to finish what I started instead of postponing it to other PRs. E.g. thanks to that I came up with a nice Given/When/Then API testing syntax
https://abs.twimg.com/emoji/v2/... draggable="false" alt="😀" title="Grijnzend gezicht" aria-label="Emoji: Grijnzend gezicht">
https://abs.twimg.com/emoji/v2/... draggable="false" alt="👇" title="Rug van hand met omlaag wijzende wijsvinger" aria-label="Emoji: Rug van hand met omlaag wijzende wijsvinger"> /9
- https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/test/java/io/eventdriven/ecommerce/testing/ApiSpecification.java
-">https://github.com/oskardudy... https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/test/java/io/eventdriven/ecommerce/api/controller/AddProductItemToShoppingCartTests.java
-https://github.com/oskardudy... href=" https://twitter.com/oskar_at_net/status/1507679632929300492">https://twitter.com/oskar_at_...
- https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/test/java/io/eventdriven/ecommerce/testing/ApiSpecification.java
-">https://github.com/oskardudy... https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/test/java/io/eventdriven/ecommerce/api/controller/AddProductItemToShoppingCartTests.java
-https://github.com/oskardudy... href=" https://twitter.com/oskar_at_net/status/1507679632929300492">https://twitter.com/oskar_at_...
Instead of doing manual threading with synchronised, Thread.sleep etc., in @eventstore Subscription to $all error handling, I found https://docs.spring.io/spring-batch/docs/current/reference/html/retry.html">https://docs.spring.io/spring-ba... and used it:
#L63">https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/main/java/io/eventdriven/ecommerce/core/subscriptions/EventStoreDBSubscriptionToAll.java #L63.">https://github.com/oskardudy... Again, throwing out code helped me to make it better and resilient /10
#L63">https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/main/java/io/eventdriven/ecommerce/core/subscriptions/EventStoreDBSubscriptionToAll.java #L63.">https://github.com/oskardudy... Again, throwing out code helped me to make it better and resilient /10
I used Spring Boot Retry also to provide long polling ( https://event-driven.io/pl/long_polling_and_eventual_consistency/).">https://event-driven.io/pl/long_p... It& #39;s a technique to make eventual consistent api, linear. If-None-Match header ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests)">https://developer.mozilla.org/en-US/doc... can help on that. See more
https://abs.twimg.com/emoji/v2/... draggable="false" alt="👇" title="Rug van hand met omlaag wijzende wijsvinger" aria-label="Emoji: Rug van hand met omlaag wijzende wijsvinger">/11 https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/main/java/io/eventdriven/ecommerce/shoppingcarts/ShoppingCartService.java">https://github.com/oskardudy...
I also added Log4J instead of System.out.println. Yup Log4J. Btw. I think that their famous "breach" was more an issue with the enterprises not having a proper dependency upgrade strategy. Everyone can be breached, but we need to be prepared for that as architects. /12
I also added CI using @eventstore and @PostgreSQL Docker images to run end-to-end integration tests. We& #39;re not living in caves anymore. It& #39;s fine to run tests against real databases /13 https://github.com/oskardudycz/EventSourcing.JVM/blob/main/.github/workflows/samples_event-sourcing-esdb-simple.yml">https://github.com/oskardudy...
If you reached here, then I hope that this thread will help you learning on my mistakes. Not always we have to do our own. Here& #39;s the full, merged sample. Feel free to send a feedback if you want to have it expanded! /14
https://github.com/oskardudycz/EventSourcing.JVM/tree/main/samples/event-sourcing-esdb-simple">https://github.com/oskardudy...
https://github.com/oskardudycz/EventSourcing.JVM/tree/main/samples/event-sourcing-esdb-simple">https://github.com/oskardudy...
Some numbers:
- 143 comments in discussions,
- 47 commits,
- 80 files changed,
- 3,906 lines of code.
That was a long run!
Thanks again for the great reviews and the lesson I got!
https://abs.twimg.com/emoji/v2/... draggable="false" alt="😅" title="Lachend gezicht met open mond en angstzweet" aria-label="Emoji: Lachend gezicht met open mond en angstzweet"> 15/15 https://twitter.com/oskar_at_net/status/1507830576358830094">https://twitter.com/oskar_at_...
- 143 comments in discussions,
- 47 commits,
- 80 files changed,
- 3,906 lines of code.
That was a long run!
Thanks again for the great reviews and the lesson I got!