Categories
Mastering Development Software

When bounded contexts and “microservices” collide. A distributed systems dilemma in diagram form

You can’t please everyone. Some people want a lot of context and background on sites like this. Others do not. If you don’t want the background, skip the first three paragraphs.

I am a software architect with about 25 years experience, starting with Amiga Basic, then C, then C++, VB6, delphi, C#, SQL (server), and more C#. Over the last 15 years my focus has been on back ends – databases, data models, and systems integration (not UI development, and certainly not modern web development with giant javascript libraries)

I currently work in a reasonably large "enterprise". By "enterprise" I mean "not a software development company". By "reasonably large" I mean our software ecosystem includes such things as an ERP (vendor code), a CRM system (vendor), an HR system (vendor), a few other vendor systems, a data warehouse, a BI stack, and a rapidly growing number of internally developed applications.

The number of internally developed applications is growing rapidly because the business wants to be able to add new functionality that is specific to us, providing market advantages, or just being able to move faster than the large vendors providing our monolithic systems. I expect this story will be familiar to many, although it probably won’t be quite so familiar to people working for pure software development companies, where you don’t have to deal with the problem of integrating with large vendor systems. If you fall into the latter category, please keep this in mind.

Enough general background.

Full disclosure, I am about to conflate "bounded context" and "domain" to some degree. Some people swear that a particular business function – such as order entry – is a single bounded context and is a natural application boundary, others say it’s a domain which can have multiple bounded contexts, which are more granular. So, depending on which camp you fall into, read the following either as "domains" or as "bounded contexts".

I have been deeply studying just about everything to do with microservices, event driven architectures, ESBs, message brokers, and other integration elements at a hectic rate over the last several months, as well as rereading Evan’s "DDD", Vernon’s "Implementing DDD", Hohpe and Woolfe’s "Enterprise Integraiton Patterns", and other famous books. And I have noticed a problem.

There are several different "primary sources" or "patterns" of advice on this topic. They all make good points. And they all contradict each other somewhere. I believe I can make the similarities and differences obvious with some simple diagrams.

Of course, the big question is "what do you want to achieve?". Well, let’s settle on things everyone seems to agree on with distributed systems: Given CAP, we are very interested in A and P, not so much C. Eventual consistency is accepted, but we don’t want one system to bring down all the rest, and we do want to partition the systems – for example into bounded contexts per Eric Evans’ DDD.

So, I want you to picture what at first seems to be a fairly "ideal" architecture according to many high profile sources, by which I mean it hits all the right notes. We have an order entry (point of sale) system. It’s a bounded context. We’re not "trying too hard to be microservicey" and creating nanoservices, and we’re also not a distributed monolith. It’s effectively agnostic about the existence of any other system in the enterprise. It’s as decoupled as it can possibly be. It has no hard temporal, logical, or availability dependencies on any other system. It looks something like this:

Decoupled orders bounded context application

One day the business comes along and says "I want order entry (or quoting) functionality in the CRM system".

Shit.

Orders plz

Now I think I can describe everything else I need to describe purely with a set images which illustrate the various approaches I’ve seen advocated over countless books, blogs, articles, lectures, and videos, making the distinction between them clear. I have never seen the options laid out quite this way, and I think doing so demonstrates that as an industry we don’t seem to have any "logically sound" solution which meets all of our principles of software architecture – except maybe the last. And I would like to hear people’s opinions on what they see.

Personally, I think option 6 is the most – and perhaps only – sane choice. In a couple of places I mention that shared library/schema definitions are "probably not a real objection". I say this because the business rules are the business rules. There’s only one set of business rules for the bounded context of orders. If the business rules change, everyone using those rules has to change. This isn’t a devops issue.

Option 1 - UI Integration

Option 2 - API Orchestration

Option 3 - Shared libraries and persistence

Option 4 - Shared libraries only

Option 5 - Shared data only

Option 6 - Shared immutable data only

Leave a Reply

Your email address will not be published. Required fields are marked *