From a legacy monolith to microservices with Domain-driven Design

From a legacy monolith to microservices with Domain-driven Design

21a532a137b506128914478ac521fc8b?s=128

Michael Plöd

April 25, 2018
Tweet

Transcript

  1. From a legacy monolith to microservices with Domain-driven Design Michael

    Plöd, @bitboss Mainz, 25. April 2018
 JAX 2018
  2. @bitboss Michael Plöd
 Principal Consultant at INNOQ Deutschland GmbH •

    Interested in Software Architecture and Domain-driven Design • Twitter: @bitboss
  3. !A monolith per se may not be a bad thing

    at all
  4. None
  5. !Domain-driven Design is no silver bullet, it won’t heal everything,

    it’s just one set of tools among others.
  6. Starting point: The monolith from the gates of hell

  7. „There is this one critical team member that knows it

    inside out“ „Woha, how could that bug pop up after we changed something at a different place?“ „We can only do integration tests, unit tests are hard to write and are not present“ „Every year the price per feature raises and so do the number of bugs in production“
  8. Let’s transform this beast to Microservices

  9. Bounded Context Context Map Shared Kernel Customer / 
 Supplier

    Conformist Anticorruption
 Layer Separate Ways Open / Host 
 Service Published 
 Language Aggregates Entities Value Objects Factories Services Repositories D D D
  10. Bounded Context Every sophisticated business (sub-) domain consists of a

    bunch of Bounded Contexts Each Bounded Context contains models and maybe other contexts The Bounded Context is also a boundary for the meaning of a given model
  11. Example 1 - You at JAX Reservations Event
 Management Badges

    JAX Visitor Name Payment Details Address Company Session Registrations Lunch Preferences Name Job Description Twitter Handle
  12. Bounded Contexts Top Down Context Maps Bottom Up Aggregates Microservice

    Candidates
  13. !Hint 1: manage expectations Often a full transformation to microservices

    will never happen. My mid-term priority would be to get to clean Bounded Contexts. After that I would consider microservices
  14. Ask the right questions Goal What are the goals you

    want to achieve by decomposing your monolith? Type What type of monolith are you dealing with? Interactions If you have modules, how are they related to each other in terms of loose coupling? Modules Which vertical / business driven modules are roughly present?
  15. ! Hint 2: quality criteria Perform an early assessment of

    the real quality criteria that are relevant for your application
  16. Perform a quality grooming workshop

  17. Types of monoliths Sort of structured Big Ball Of Mud

  18. Sort of structured monolith Not just horizontal but also some

    vertical slices / modules / components Still a lot of cross references between those verticals
  19. Possible approach Steps 1 Try drawing a context map of

    your monoliths. Use the currently present vertical slices as a starting point and match the patterns on them 4 Start with one of the 2-3 migration steps by either pulling out a microservice or by refactoring towards a better internal structure 3 Match the findings of the previous steps with your migration goals and chose 2-3 initial migration steps 2 Identify hot spots and possible quick wins based on the context maps
  20. Big Ball Of Mud monolith Some kind of horizontal layering

    but no vertical slices / modules Unstructured cross referencing. Everything can and does reference anything else
  21. Possible approach Steps 1 Drawing a context map as a

    starter will hardly work here. So you should come up with a short list of „business module wise“ pain points 4 Start pulling out bounded contexts with aggregates towards microservices 3 After having introduced aggregates you may introduce bounded contexts as a next step. Still in the monolith 2 Refactor to aggregates, step by step. Move away from the procedural service driven anemic domain model. Don’t think about microservices at this stage.
  22. ! Hint 3: baby steps Never perform a big bang

    migration. Work in small steps and each step should deliver an improvement.
  23. Top Down Bottom Up Bounded Contexts Context Maps Aggregates

  24. Context Map The Bounded Context by itself does not deliver

    an overview of the system By introducing a Context Map we describe the contact between models / contexts The Context Map is also a great starting point for future transformations
  25. Context Map Patterns by the books Shared Kernel Customer /

    Supplier Conformist Anticorruption Layer Separate Ways Open / Host Service Published Language Eric Evans defined those seven context mapping patterns and did not organize them any further. Also Vaughn Vernon stuck to this way of describing them. However we will classify them in: • Upstream Patterns • Downstream Patterns • In-Between Patterns In addition to that we will introduce an eighth pattern.
  26. Upstream / Downstream Credit Agency Scoring Call Flow Model Flow

    Focus of 
 Context Map Upstream System Downstream System
  27. Context Map Patterns Categorized Credit Agency Scoring Model Flow Upstream

    System Downstream System Upstream Patterns: • Open Host Service Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
  28. Context Map Patterns Categorized Credit Agency Scoring Model Flow Upstream

    System Downstream System Upstream Patterns: • Open Host Service Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
  29. Open Host Service Upstream System Downstream System Each Bounded Context

    offers a defined set of services that expose functionality for other systems. Any downstream system can then implement their own integration. This is especially useful for integration requirements with many other systems. SOAP / REST for example
  30. Idea: Event Publisher Upstream System Downstream System A Bounded Context

    publishes Domain Events. This can be done by messaging or feeds. Other Bounded Contexts may subscribe to those events in order react upon them. This is a new pattern, which is not part of the DDD books by Eric Evans or Vaughn Vernon publishes
  31. Context Map Patterns Categorized Credit Agency Scoring Model Flow Upstream

    System Downstream System Upstream Patterns: • Open Host Service Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
  32. Customer / Supplier Upstream System Downstream System There is a

    customer / supplier relation ship between two teams. The downstream team is considered to be the customer, sometimes with veto rights. Downstream Team discusses model with Upstream Team
  33. Conformist Upstream System Downstream System The downstream team conforms to

    the model of the upstream team. There is no translation of models and no vetoing. If the upstream model is a mess, it propagates to the downstream model. The Downstream Team adapts to the model of the Upstream Team
  34. Anticorruption Layer Upstream System Downstream System The anticorruption layer is

    a layer that isolates a client’s model from another system’s model by translation. External model to internal model transformation
  35. Context Map Patterns Categorized Credit Agency Scoring Model Flow Upstream

    System Downstream System Upstream Patterns: • Open Host Service Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
  36. Shared Kernel Upstream System Downstream System Two teams share a

    subset of the domain model including code and maybe the database. Shared Kernel
  37. Published Language Upstream System Downstream System Published Language is quite

    similar to Open Host Service. However it goes as far as to model a Domain as a common language between bounded contexts. A typical example is the ISBN in the book publishing domain Implements according to Published Language Implements according to Published Language
  38. Separate Ways There is no connection between the bounded contexts

    of a system. This allows teams to find their own solutions in their domain. However there may be a „hidden“ connection between the teams. Look out of for „organizational“ Solutions (Excel, Access, ..)
  39. Context Map Patterns Categorized Credit Agency Scoring Model Flow Upstream

    System Downstream System Upstream Patterns: • Open Host Service Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
  40. Context Maps and Conway’s Law Team independence Tight Coupling /

    Integration Shared Kernel Customer / Supplier Conformist Anticorruption Layer Separate Ways Open / Host Service Published Language Team Communication Event Publisher
  41. Example: Context Maps https://github.com/mploed/ddd-strategic-design-spring-boot https://github.com/mploed/ddd-strategic-design-spring-boot

  42. U D D D U U U U D D

    Example: Context Maps Credit
 Application Scoring Credit
 Agency Customer Customer
 Contact O
 H
 S OHS C
 F S K CF E
 P A
 C
 L ACL EP
  43. Where do Context Maps help? Governance A Context Map helps

    to identify governance issues between applications and teams. Transformation A Context Map is an excellent starting point for future transformations: it gives an in-depth insight into integration aspects and subdomain / context relations Bad Models By introducing a Context Map we get a clear view on where and how bad models propagate through application landscapes Politics By not just looking at technical integration aspects the Context Map also helps us in seeing how teams communicate and „play politics“.
  44. Top Down Bottom Up Bounded Contexts Context Maps Aggregates

  45. Building Blocks help designing 
 the internals of
 Bounded Contexts

    Aggregates (Internal) 
 Building Blocks Entities Value Objects Factories Services Repositories
  46. 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
  47. 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
  48. 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
  49. Building
 Blocks Aggregates Do not underestimate the power of the

    Aggregate
  50. Building
 Blocks Aggregates <ValueObject> SelfDisclosure <ValueObject> Address <ValueObject> RedemptionDetail <Entity>

    Loan <Entity> Customer <Entity> LoanApplicationForm <Root Entity> <Entity> Aggregates group Entities. The Root Entity is the lead in terms of access to the object graph and lifecycle.
  51. Building
 Blocks Aggregates <ValueObject> SelfDisclosure <ValueObject> Address <ValueObject> RedemptionDetail <Entity>

    Loan <Entity> Customer <Entity> LoanApplicationForm <Root Entity> <Root Entity> Take a look at this approach which is more fine grained
  52. 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
  53. 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
  54. 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
  55. 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
  56. Let’s look at some aggregates

  57. Bounded Contexts Top Down Context Maps Bottom Up Aggregates Microservice

    Candidates
  58. > https://leanpub.com/ddd-by-example > Follow me on Twitter: @bitboss Thank you

    very much!