Exploring DDD, CQRS, and Event Sourcing: Insights from a complex project
Tags: eventdriven, ddd, eventsourcing, microservices
Published: 2024-05-11 19:42:34

After years of developing monolithic applications with Java and Spring, typically following a traditional three-layer architecture, I recently had the opportunity to join a new project that relies on a highly modular approach with distinct microservices. I'd like to share my thoughts and insights on this experience.

## The Project
Homiris is a widely used alarm system in France and Belgium, serving around 600,000 clients. To support this project, EPS, the company that sells Homiris, has built an extensive microservices application that manages every stage of the product's lifecycle.

This application is continuously connected to secure areas and analyzes incoming data to activate alarms in case of intrusions. Additionally, it oversees client data, contracts, billing, equipment issues, and handles communication such as sending emails, SMS messages, and even prints letters.

The project employs a Domain-Driven Design (DDD) architecture, with all microservices communicating through Kafka, following the Command Query Responsibility Segregation (CQRS) and Event Sourcing patterns.


## What I liked about the project
- Working with a microservice architecture challenges you to think abstractly and decide how deeply to split each service. This mindset not only enhances your programming skills but also influences other decisions you take as programmer, like choosing class structures or database design.

- Dividing microservices while ensuring loose coupling helps establish a solid foundation for unit tests, strengthening the application.

- Implementing CQRS and Event Sourcing introduced me to a new way of building programs. With storage costs being affordable nowadays, the application is very open to duplicating data between microservices. 
For instance, consider a microservice managing client personal information and another handling email and SMS communication. By employing CQRS and Event Sourcing, we duplicated client information in the second microservice, ensuring its independence when launching email or SMS campaigns, and it also contributed to the performance of the application.

- In this project, the team developed a custom library serving as a framework. This library offers classes tailored for logging, error handling, context management, and interaction with Kafka, among other functionalities. I believe that having this internally developed and maintained library, instead of relying directly on third-party or Spring Boot libraries. It provides a layer that aligns with the project's specific requirements and terminology, minimizing code repetition, and streamlining the development process for team members.

- DDD greatly facilitates project integration for every developer. It enhances communication between technical and non-technical teams.

## What needs to be impoved
- DDD is great, but it must be respected in all aspects, or it will work against the team's productivity. It's necessary to consistently use only one term when referring to something. In this project, this aspect wasn't fully respected. For example, the box installed in houses to communicate with project was referred to by three names: 'La Passerelle', 'La Centrale', or sometimes 'Alarme', which disrupted the integration of new developers.

- To name the microservices, the team opted for three-character names such as 'TNS' or 'TPC'. Certain regulations were established, like starting with a 'T' for transverse microservices, or 'P' for portals. However, I find this naming convention challenging to remember, and it's prone to name collisions. I believe selecting more human-readable names would be more beneficial for the project.

- As a web developer, I've always preferred conducting end-to-end testing locally before delivering code. However, this process wasn't straightforward with this project. Running multiple microservices consumed significant time and resources, often requiring testing directly on the development environment. This practice resulted in delays in development.

- Homiris is a French product. To adhere to DDD, we had to use many French terms in our code. Mixing French and English in code isn't very aesthetically pleasing, and it's also challenging to determine when to transition from French to English. For example, do we write `isPasserelleEnErreur`, `isPasserelleOnError`, or `isPasserelleOnErreur`? This decision often leads to confusion (as if naming was ever easy before 😝).


## Final thoughts
In conclusion, while the experience of integrating this project was challenging, it offered valuable insights into handling complexity in a new way. While Domain-Driven Design (DDD) proves beneficial for large companies, it requires careful attention to its principles to avoid slowing down team productivity. Furthermore, the implementation of CQRS and Event Sourcing proved invaluable, particularly in enhancing performance and scalability, crucial aspects for any project. However, there are areas for improvement, such as ensuring consistency in terminology and adopting more intuitive naming conventions for microservices. Additionally, making the end-to-end testing process more efficient is essential to avoid delays in development.