Implementing DDD with the Spring ecosystem

Implementing DDD with the Spring ecosystem

Domain-Driven Design is currently a very popular way of implementing and looking at Microservices. This session aims at giving you a kickstart how to work on the implementation details of DDD in the Spring Ecosystem. We will take a look at how to model your microservices with Bounded Contexts and Strategic Design, after that we will dive into a Microservice and look at how to implement Aggregates, Repositories and how to work with Domain Events. All the implementation details will leverage various Spring technologies such as Spring Boot, -Data and -Cloud. This talk consists of a bit of theroy and a lot of code.

21a532a137b506128914478ac521fc8b?s=128

Michael Plöd

May 24, 2018
Tweet

Transcript

  1. 2.

    Disclaimer Michael Plöd - innoQ
 @bitboss Most of these ideas

    do not come from me personally. I have to thank Eric Evans and Vaughn Vernon for all the inspiration and ideas. If you haven’t: go out and get their amazing books!
  2. 3.

    Feel free to replace developer by architect, team lead, team

    member or domain expert. Nothing in this talk is a silver bullet.
  3. 4.

    Bounded Context Spring Spring Core Spring Boot Spring Data Spring

    Cloud Spring MVC Spring Events Good OO 
 practice Aggregates Entities Value Objects Factories Services Repositories TOPICS I will talk about today
  4. 6.

    Bounded Context Context Map Shared Kernel Customer / 
 Supplier

    Conformist Anticorruption
 Layer Separate W ays Open / Host 
 Service Published 
 Language STRATEGIC DESIGN helps us with regards to business capabilities
  5. 7.

    Bounded Context Every sophisticated business (sub-) domain consists of a

    bunch of Bounded Contexts Each Bounded Context contains a domain model, don’t nest Bounded Contexts The Bounded Context is also a boundary for the meaning of a given model
  6. 8.

    Example - You at spring.io Reservations Event
 Management Badges spring.io


    Visitor Name Payment Details Address Company Session Registrations Lunch Preferences Name Job Description Twitter Handle
  7. 13.

    Aggregates (Internal) 
 Building Blocks Entities Value Objects Factories Services

    Repositories TACTICAL DESIGN helps us with regards to evolvability of microservices
  8. 14.

    Building
 Blocks Entities Entities represent the core business objects of

    a bounded context’s model Each Entity has a constant identity Each Entity has its own lifecycle Customer Credit Application Shipment
  9. 15.

    Building
 Blocks Value Objects Value Objects derive their identity from

    their values Value Objects do not have their own lifecycle, they inherit it from Entities that are referencing them You should always consider value objects for your domain model Color Monetary Amount Customer
  10. 16.

    Building
 Blocks Is „Customer“ an Entity or 
 a Value

    Object If an object can be considered an Entity or a Value Object always depends on the (Bounded Context) it resides in. Customer Example: A customer is an entity in a CRM-like microservice but not in a microservice that prints badges, there we are just interested in name, job description and Twitter handle
  11. 19.

    Building
 Blocks Aggregates <ValueObject> SelfDisclosure <ValueObject> Address <ValueObject> RedemptionDetail <Entity>

    Loan <Entity> Customer <Entity> LoanApplicationForm <Root Entity> <Root Entity> Aggregates group Entities. The Root Entity is the lead in terms of access to the object graph and lifecycle.
  12. 20.

    Best Practices for Aggregates Hints Small Prefer small aggregates that

    usually only contain an Entity and some Value Objects. Consistency Boundaries Take a look which parts of your model must be updated in an atomically consistent manner One TX per Aggregate Aggregates should be updated in separate transations which leads to eventual consistency Reference by Identity Do not implement direct references to other Root Entities. Prefer referencing to Identity Value Objects
  13. 22.

    Building
 Blocks Aggregate Example Battery of an electric car Battery

    Cells Status Charger Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell General Information
  14. 23.

    Building
 Blocks Aggregate Example Battery of an electric car Think

    about good a good old OO practice: information hiding Personal opionion: In the advent of POJOs we have unlearned information hiding A blind „Genereate Getters and Setters“ in your IDE is your enemy Battery Cells Status Charger Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell General Information
  15. 24.

    Building
 Blocks Aggregate Example Battery of an electric car Do

    we need an external access to the cells? Stuff we want to do from the outside: - Start charging - Get current charge level - Get information about the charging Battery Cells Status Charger Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell Cell General Information
  16. 25.
  17. 26.

    Hints Visibility Use the power of your programming language, private

    Attributes with public getters and setters are no information hiding. Yes, you can have classes with a package visibility level. Packages Place each aggregate in its own package and work with package level visibility References I prefer Aggregates that do not reference themselves, they are hooked together with a few shared value objects which leads to more decoupling
  18. 27.

    Applicant Address Account
 Balance Scoring
 Result Scoring Calculations Score Color

    AgencyResult KoCriteria Warning
 Message Financial
 Situation Incomings Outgoings PersonId Application
 Number
  19. 30.

    Adapter Adapter Adapter Adapter Adapter Adapter Adapter Adapter Web Mobile

    Cloud Messaging Database Document GraphDB Messaging Core
 
 
 
 Domain
  20. 31.

    The hexagonal architecture is not your only option and is

    not suitable for everything „The domain should be the heart of a system“ Hexagonal ➡ For bounded contexts with a lot of logic and calculations ➡ Complex ➡ Many mappings ➡ Good fit for the DDD internal building blocks CRUD ➡ For bounded contexts that just store and read data ➡ Keep it simple ➡ Spring Data Rest may be your friend Query Driven ➡ For bounded contexts that perform complex queries ➡ Mostly based on a read model ➡ Sometimes the „Q“ in distributed CQRS
  21. 35.

    Credit
 Application
 Submitted Event We can use Domain Events for

    the communication between Bounded Contexts. This leads us to Event-driven Applications
  22. 37.

    An event is something 
 that happened in the past

    t now Event Event Event Event Event
  23. 38.

    Options for Event Payload Options Full Payload The event carries

    complete Entitiy-Graphs or Aggregates Mix The event contains data that is usually of interest to many other contexts. For special purposes there is also a URL to a RESTful HTTP Ressource Empty The event is empty or contains only minimal data and is being used to trigger pulling from a feed (eg. Atom) REST URL The event only carries a URL to a RESTful HTTP Ressource
  24. 39.
  25. 40.

    Spring Cloud Stream Broker Very often the de-facto choice for

    many distributed systems. Typical choices nowadays would be Apache Kafka or RabbitMQ. High degree of decoupling. Internal 
 Event Bus Only JVM internal with synchronous and / or asynchronous options. Highly recommended for building decoupled monoliths. HTTP Feeds REST + Events = Feeds
 
 Often ignored option in which you won’t need a dedicated broker. Spring MVC + Quartz 
 + Rome Spring Application Events