Domain Driven Design is a really good tech
A domain can be a business domain at the highest level (e.g LifeInsurance, Vehicle Insurance) or a sub domain within the business domain (e.g Life Insurance Claim, Motor Insurance Claim, Vehicle Insurance Claim etc)
Notice some domains are core to your business, i.e. they hold the secret-sauce that brings in the revenue while the other domains are supporting. A core domain is core because of the business value it brings
A Bounded context is a term from Domain Driven Design (DDD) and represents a linguistic boundary within or across a domain.
The interaction across bounded contexts happens with the exchange of a model – one sends its internal representation of a concept across to another or consumes a model from another. DDD context interaction patterns describe these as “Upstream” or “Downstream” relationships and help show where an external model is influencing a bounded context
We examine the importance of “how” models get propagated across context boundaries, specifically with an example where a “buying context” is coupled with “customer management” context leading to poor experience
How models propogate
Models propogate across boundaries via domain actions containing the model. These can be an API or Event. You should already sense an problem with this statement as the term “Domain events” now conflicts with the above statement
APIs are blocking interactions where as Events follow an asynchronous publish/subscribe model. APIs are ubiquitous as consumer systems offer endpoints for inbound integrations and the perception of real-time update beats an delayed synchronisation in our collective imagination
Dealing with slow or unresponsive APIs can be tolerated in certain circumstances however band-aid solutions can end up hurting user experience and damage your product’s reputation, pushing customers away
Good API design can help remediate this but it requires upfront understanding of how the customer facing systems are interacting with the internal systems & what their needs are
For example, simply throwing a cache & reading slightly stale information might be sufficient in a Query context – but how do you fix a Command API that is slow or unresponsive?
We look at some key concepts to break apart interactions and solve for X
Know your Contexts
Imagine you are in the business of selling coffees to happy customers and all you need is a point-of-sale system (let us imagine you have an endless tap of fresh coffee). Your business is all about selling then and you only operate in a single context
You may also define this as “We interact with the customer in a single context”, but let me warn you – you might be stretching to definition of a customer here (at-least from a technology implementation standpoint). I would argue they are mere transactional contacts vs true customers in the system (we will see why later)
Let us now imagine your coffee shop now need to send out birthday coupons to your customers via email/sms etc. You may need to even call them and wish them (if they permit you) and so on
This act of recognising someone who is transacting with you and asking them for their preferences, interacting with them, offering them rewards for being a customer etc is different from selling coffee – welcome to the Customer Management context
Okay so your business has two contexts, Selling Coffee and Managing Customers. Are they the same or different? What actions can you not do in both without impacting efficiency? How about capturing information (even if it on a bit of paper) in the two contexts about a person?
Most of us, who have never run a busy business, mix the two and have things work in them interchangeably. This works most of the time but it can lead to serious issues down the line if we do not draw boundaries and divide the actions and information across the contexts.
Ever been to a coffee shop where you waited a long time because the 1 worker was busy on the phone talking to a customer about their birthday plans? The worker was doing their job well in the customer management context but failed in the selling / transactional context
Contexts help define the actions, language and information while boundaries help define interactions. For engineers, this is vital as it helps design the connectivity as we have to often chose between consistency of information or availability of a service within networked or distributed systems
So why could your API be killing your Customer Experience?
APIs designed without consideration of context boundaries can end up coupling two contexts. Imagine an API for Contact creation in CRM which adds direct dependency in our coffee shop example. This API is sending data in real-time between a Selling context and Customer Management context, fine and can block or error the selling transaction if there are network delays or data issues in the CRM record, not fine!
We need to carefully consider interactions between context and introduce non-blocking interactions (and anti-corruption layers) to let business happen. Make Systems Integration Great Again!
In summary, services within a context have high cohesion and services across contexts should have low coupling. Bad API design (no not the RAML/OAS stuff but the solid/dotted arrow stuff) can couple two independent business contexts
If we carefully model our interactions by consciously recognising our contexts and boundaries then we can built for business transactions more efficiently and open up possibilities for future connectivity and growth