Microservices
Domain-driven DesignMichael Plöd, @bitboss
<3
Microservices
Domain-driven DesignMichael Plöd, @bitboss
<3
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!
Feel free to replace developer by architect, team lead, team member or domain expert.
Neither Domain-driven Design nor Microservices are silver bullets that solve all your problems just by applying them.
Model your Microservices along business capabilities
Bounded Context
Context Map
Shar
ed K
erne
l
Cust
omer
/
Supp
lier
Conf
orm
ist
Antic
orru
ptio
n La
yer
Sepa
rate
Way
s
Ope
n / H
ost
Serv
ice
Publ
ished
La
ngua
ge
STRATEGIC DESIGN helps us with regards to
business capabilities
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
Example - You at JUG Saxony Day
ReservationsEvent
Management BadgesJUG Saxony Day
VisitorName
Payment Details
Address
Company
Session Registrations
Lunch Preferences
Name
Job Description
Twitter Handle
A Bounded Context is the
BOUNDARY for the meaning of a model
Don’t Repeat Yourself
Don’t Repeat Yourself
INSIDE of a
Bounded Context
Repeat Yourself
BETWEEN several
Bounded Contexts
Cut your
Microservices
along
Bounded Contexts
Don’t Repeat Yourself
INSIDE of a
Bounded Context
Mic rose rvi c e
Repeat Yourself
BETWEEN several
Bounded Contexts
Mic rose rvi c e s
Yo u may wan t to
Mind Conway’s Law when dealing with communication
between Microservices
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
Eric Evans defined those seven context mapping patterns
Context Map Patterns by the books
Shared Kernel
Customer / Supplier
Conformist
Anticorruption Layer
Separate Ways
Open / Host Service
Published Language
Vaughn Vernon added two more patterns to the list
Context Map Patterns by the books
Shared Kernel
Customer / Supplier
Conformist
Anticorruption Layer
Separate Ways
Open / Host Service
Published Language
Partnership
Big Ball Of Mud
Communication between Contexts
Call Flow
How are calls and events flowing within a system / context
landscape?
Model Flow
How do models propagate between systems? Where are
boundaries?
Affect
How do the actions of one team / context affect other teams /
contexts?
or or
Team Communication /
Politics
How do teams communicate with each
other? Where are politics being played?
or or
Upstream / DownstreamCredit Agency
Scoring
Affect Flow Focus of Context Map
Upstream System
Downstream System
The aim of the
Context Map
should be a
holistic overview
of a system landscape
Issues of the existing model according to my personal experience
Open Host Service
The Open Host Service is often described as a standalone pattern and that just the Anticorruption Layer can be combined with it. The interface in the definition has an imperative „touch“ to it.
NotationThere are only a few ideas for a formal notation of context maps in the current literature.
Upstream / Downstream
The upstream / downstream patterns very often relate to interfaces on the upstream side, which are basically Open Host Services.
UncertaintyI have witnessed a lot of uncertainty in teams I have worked with with regards to the definitions of Published Language and Separate Ways.
Context Map Patterns CategorizedCredit Agency
Scoring
Upstream System
Downstream System
Mostly Upstream Patterns: • Open Host Service
Mostly Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer
In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
Context Map Patterns CategorizedCredit Agency
Scoring
Upstream System
Downstream System
Mostly Upstream Patterns: • Open Host Service
Mostly Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer
In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
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
Context Map Patterns CategorizedCredit Agency
Scoring
Upstream System
Downstream System
Mostly Upstream Patterns: • Open Host Service
Mostly Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer
In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
Customer / Supplier
Upstream System
Downstream System
There is a customer / supplier relation ship between two teams. The down-stream team is considered to be the
customer, sometimes with veto rights.
Downstream Team discusses model with
Upstream Team
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
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
Context Map Patterns CategorizedCredit Agency
Scoring
Upstream System
Downstream System
Mostly Upstream Patterns: • Open Host Service
Mostly Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer
In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
Shared Kernel
Upstream System
Downstream System
Two teams share a subset of the domain model including code and maybe the
database.
Shared Kernel
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
Example: ISBNAn ISBN is assigned to each edition and variation (except reprintings) of a book. For example, an ebook, a paperback, and a hardcover edition of the same book would each have a different ISBN. The ISBN is 13 digits long if assigned on or after 1 January 2007, and 10 digits long if assigned before 2007. An International Standard Book Number consists of 4 parts (if it is a 10 digit ISBN) or 5 parts (for a 13 digit ISBN):
1. for a 13-digit ISBN, a prefix element – a GS1 prefix: so far 978 or 979 have been made available by GS1,
2. the registration group element (language-sharing country group, individual country or territory),
3. the registrant element, 4. the publication element, and 5. a checksum character or check digit.
A 13-digit ISBN can be separated into its parts (prefix element, registration group, registrant, publication and check digit), and when this is done it is customary to separate the parts with hyphens or spaces. Separating the parts (registration group, registrant, publication and check digit) of a 10-digit ISBN is also done with either hyphens or spaces. Figuring out how to correctly separate a given ISBN is complicated, because most of the parts do not use a fixed number of digits.
Source: https://en.wikipedia.org/wiki/International_Standard_Book_Number
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, ..)
Context Map Patterns CategorizedCredit Agency
Scoring
Upstream System
Downstream System
Mostly Upstream Patterns: • Open Host Service
Mostly Downstream Patterns: • Customer / Supplier • Conformist • Anticorruption Layer
In-Between Patterns: • Shared Kernel • Published Language • Separate Ways
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
C
omm
unic
atio
n
U
D
D
D
U
U
U
D
Example: Context Maps
Credit Application
Scoring Credit AgencyCustomer
CustomerContact
OHS
OHSCF
S K
CFACL
OHS
? Where are Big Ball Of Mud and / or Partnership
U
D
D
D
U
U
U
D
How about adding them as flags?
Credit Application
Scoring Credit AgencyCustomer
CustomerContact
OHS
OHSCF
S K
CUSACL
EP
BBOM
Partnership
Microservice architectures should be evolvable
Aggregates
(Internal) Building Blocks
Entities
Value Objects
Factories
Services
Repositories
TACTICAL DESIGN
helps us with regards to evolvability of microservices
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
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 themYou should always consider value objects for your domain model
Color
Monetary Amount
Customer
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
Value Objects
ExpressivenessValue Objects add expressive names to key concepts in a model and increase the conceptual cohesiveness of objects.
Focus for Entities
Value Objects allow entities to focus on identity by delegating behavioral logic to them.
Domain Concepts
Value Objects enable moving from using primitives for simple domain concepts like postcode of an address.
Contrary to
Data Transfer Objects
which only are there for transporting data back and
forth
Value Objects represent behavior of the
business domain
Entity
Value Value
Using only Entities and Value Objects you will end up with
big object graphs
Issues related to big object graphs
Issues
NavigationEndless navigation possibilities lead to less understandable code and is harder to maintain. Mind the „Law Of Demeter“.
ConsistencyBig object graphs usually lead to large transactional boundaries and to a „everything must be consistent right now“ attitude.
Cascading of errors
The bigger the object graph, the easier it is for bugs to propagate or to pop up at places no one would expect.
TestingBig and growing object graphs are hard to test. Sooner or later you end up with a ton of mocks.
Loose Coupling
+
Information Hiding
+
CohesionLets talk about
Entity
Value Value
Neither loose coupling, nor information hiding or cohesion are achieved with large object
graphs
Building Blocks Aggregates
Do not underestimate the power of the Aggregate
Aggregates group Entities and Value Objects
ROOT ROOT
ROOT ROOT
Each Aggregate has a Root Entity, aka Aggregate Root
Hints for Root
Entities
LifecycleThe Root Entity controls the Aggregate’s lifecycle. This is obvious with Aggregates that only contain one Root Entity. The Root Entity can also overrule the lifecycle of other Entities in the Aggregate.
FacadeThe Root Entity can be seen as a higher level facade offering an API for the Aggregate.
Entry PointThe only reference to an Aggregate may be the Root Entity. It is not allowed to reference other classes of the aggregate.
<ValueObject> SelfDisclosure
<ValueObject> Address
<ValueObject> RedemptionDetail
<Entity> Loan
<Root Entity>LoanApplicationForm
<Root Entity><ValueObject> CustomerNumber
<Root Entity> Customer
Consider using Value Objects as indirect references between Aggregates
Aggregates Domain
ConceptsAggregates represent higher level business concepts.
BehaviorTry moving behavior to Value Objects in the Aggregates. The Entities should deal with lifecycle and identitiy.
InvariantsAggregates allow us to implement and enforce rules and invariants (a fincancial situation must have in- and outgoings)
Connascence „In software engineering, two components are connascent if a
change in one would require the other to be modified in order to maintain the overall correctness of the system.“
https://en.wikipedia.org/wiki/Connascence
Best Practices for Aggregates
Hints
SmallPrefer 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 transactions which leads to eventual consistency
Reference by Identity
Do not implement direct references to other Root Entities. Prefer referencing to Identity Value Objects
Adapter
Adapter
Adapter
Adapter
Adapter
AdapterAdapter
Adapter
Web
Mobile
Cloud
Messaging
Database
Document
GraphDB
Messaging
Core
Domain
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
Mind Microservice integration styles
Orchestration vs
Choreography
Building Microservices by Sam Newman, O'Reilly
Event Stream
ChoreographyOrchestration
Choreography
Credit Application
Scoring Credit DecisionCustomer
CreditApplicationSubmitted
Event
Credit ApplicationSubmitted
Event
We can use Domain Events for the communication between Microservices.
This leads us to Event-driven Microservices
!Model information about activity in the domain as a series of discrete events.
An event is something that happened in the past
t
now
EventEventEventEventEvent
Triggers of Events
DocumentsApplications
User Actions
Other Events
Time
How do I identify events?
Event Storming!
Invite the right people
Provide unlimited modelling space
Explore the domain starting from Domain Events
Explore the the origins of Domain Events
Look for Aggregates
Source: http://ziobrando.blogspot.de/2013/11/introducing-event-storming.html
Avoid tables / chairs in the room
Command
Aggregate
Domain Event
External System
ReadModel
Policy
Command
on
on
returns
returns
updates
triggers
invokes
invokes
REST + Events =
Feeds
Application Approved
Event
Credit Decision
The Credit Decision Microservice publishes the
Application Approved Events as an Atom Feed via HTTP
Contract Offers
The Contract Offers Microservice polls the HTTP
based Atom Feed at a predefined rate
Characteristics of Feeds
Feeds
HTTPYou can leverage the full featureset of HTTP for the feeds on the client and the server side: ETags, Last Modified Headers, pagination, links or conditional requests.
Hybrid CloudFeeds come in handy when dealing with a hybrid cloud scenario because HTTP is always the easiest way to communicate between on premise and public networks.
InfrastructureYou won’t need an additional infrastructure for implementing feeds. All you need is HTTP, no message brokers.
RESTBy using feeds you can mitigate some challenges that you face when going for a full synchronous scenario. You still need service discovery but resilience is easier to handle.
In order to offer Feeds we must?
Persist our Domain Events!
Event Sourcing is an architectural pattern in which the state of
the application is being determined by a
sequence of events
Using the ideas behind CQRS we can derive views that are optimized for queries from the event store
Migrating from monoliths to Microservices
Starting point: The monolith
from the gates of hell
Bounded Contexts
Top Down
Context Maps
Bottom Up
Aggregates
Microservice Candidates
Top-Down Approach
Steps
1Try drawing a context map of your monoliths. Use the currently present vertical slices as a starting point and match the patterns on them.
4Start with one of the 2-3 migration steps by either pulling out a microservice or by refactoring towards a better internal structure.
3Match the findings of the previous steps with your migration goals and chose 2-3 initial migration steps.
2Identify hot spots and possible quick wins based on the context maps.
Bottom-Up Approach
Steps
1Come up with a short list of „business module wise“ pain points.
4Start pulling out bounded contexts with aggregates towards microservices.
3After having introduced aggregates you may introduce bounded contexts as a next step. Still in the monolith.
2Refactor to aggregates, step by step. Move away from the procedural service driven anemic domain model. Don’t think about Microservices at this stage.
! Never perform a big bang migration. Work in small
steps and each step should deliver an improvement.
Microservices
Domain-driven DesignMichael Plöd, @bitboss
<3