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 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
1/
https://github.com/oskardudycz/EventSourcing.JVM/pull/1
I 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/ /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
It enables concise and precise modelling /3 https://twitter.com/oskar_at_net/status/1506998215714955268

I'm a huge fan of slicing architecture vertically ( https://event-driven.io/en/how_to_slice_the_codebase_effectively/). 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 /4
Spring Boot has a built-in ApplicationEventPublisher ( https://reflectoring.io/spring-boot-application-events-explained/), so there'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't want to handle them in code, then it'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
Btw. for the global exception handling, you can use ControllerAdvice and ExceptionHandler annotation like that
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

As I'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'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 
/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/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/test/java/io/eventdriven/ecommerce/api/controller/AddProductItemToShoppingCartTests.java
- https://twitter.com/oskar_at_net/status/1507679632929300492


- 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/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/test/java/io/eventdriven/ecommerce/api/controller/AddProductItemToShoppingCartTests.java
- https://twitter.com/oskar_at_net/status/1507679632929300492
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 and used it:
https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/main/java/io/eventdriven/ecommerce/core/subscriptions/EventStoreDBSubscriptionToAll.java#L63. Again, throwing out code helped me to make it better and resilient /10
https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/main/java/io/eventdriven/ecommerce/core/subscriptions/EventStoreDBSubscriptionToAll.java#L63. 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/). It's a technique to make eventual consistent api, linear. If-None-Match header ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests) can help on that. See more
/11 https://github.com/oskardudycz/EventSourcing.JVM/blob/main/samples/event-sourcing-esdb-simple/src/main/java/io/eventdriven/ecommerce/shoppingcarts/ShoppingCartService.java

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're not living in caves anymore. It'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
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'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/oskardudycz/EventSourcing.JVM/tree/main/samples/event-sourcing-esdb-simple
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!
15/15 https://twitter.com/oskar_at_net/status/1507830576358830094
- 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!
