Over the years, there has been lots of “back-end” forth over Service Oriented Architecture, Event Driven Architectures, Microservices, CQRS, DDD…
I’d like to offer a truce, a unified view of the proverbial elephant and the blind men, a potent recipe to “break the monolith” without ending up building a distributed one.
Before we start, I’d like to reiterate on some of the biggest misconceptions of what a “Service” is and how it should be built:
1/ “A service typically implements a set of distinct features or functionality, such as order management, customer management”
3/ Traditional Software Engineering principles (such as Cohesion and loose-coupling) apply
It does not matter how good your stock photography or how humorous your presentation are, these are the absolute anti-patterns of Service Design.
Over the years, I have argued that:
The fundamental goal of service is to ensure a consistent outcome for any given intent
Services are therefore not autonomous, but they enable Systems of Record to be autonomous
Traditional software engineering principles do not apply, because Service Oriented Architectures are built in a broad set of innovative software engineering concepts such as: bi-directional interfaces, assemblies, orchestration languages, extensible and semantically accessible data structures.
What I find fascinating is that most of the SOA literature and counter literature has failed to mention the C word, the core problem addressed by Service Oriented Architecture: Consistency, the eventual kind, and instead focused on perhaps the biggest misconception of all:
4/ Services are stateless
One cannot understand Service Oriented Architecture and IT in general without understanding eventual consistency. Only the kids who grew their app around a single data store think that “breaking the monolith” is a new problem. IT has broken the monolith eons ago and achieved consistency (usually, at night) with ancient, but robust, file based synchronization mechanisms. Of course these kinds of timeframes and mechanisms are no longer relevant in the age of Uber or PayPal, but the underlying landscape has not fundamentally changed from what it looked like twenty years ago.
So, I’d like to offer a taxonomy that we can all agree on, and stop opposing one versus the other:
Image may be NSFW.
Clik here to view.
It all starts, of course with the systems of record, which expose “microservices” (I generally call them integration points to avoid using the word “Service”). Services themselves are focused on enabling consistency both in delivering data (from the System of truth) to updating a set of systems of record.
APIs are focused on the enabling the consumption of services in the context of specific activities, in particular when it comes to managing channels (mobile, Web, wearables…).
Of course there is an “Event Driven” view of that architecture, but it does not fundamentally change the topology, you still have to achieve consistency in one way or another (pub/sub in that case):
Image may be NSFW.
Clik here to view.
The problem, as I see it is that, in the small, APIs, Services and Microservices can all directly be exposed to a consumer, but in the large, can they really be arbitrarily consumed when consistency and omnichannel requirements need to be accounted for?
Happy to hear your feedback on that taxonomy, in part II we’ll talk about managing interface contracts in that context.