A Path to Microservices or a Destination Itself
When looking to build a microservice, you may have come across two pieces of advice; start with a monolith, and don’t start with a monolith. For a good number of us developers in the trenches, the point looks irrelevant because we already have a monolith, so one to-do completed and moving on. Not so fast! The discussion goes beyond the greenfield experience of where to start. Instead, within the “don’t start with a monolith” advice is another architecture that bears investigating further, greenfield or brownfield, the Self-Contained Systems (SCS).
Both points of view agree that it is essential to understand your system’s domain and to divide your services according to the domain’s bounded contexts. In fact, experiential understanding of the domain would be a major point behind building the monolith first as advised. Domain-Driven Design (DDD) concepts are consistently referenced in discussions regarding microservices; context mapping, distillation, and aggregates, to name a few. Therefore, I would suggest that you add some “Just Enough Design” steps for domain definitions into your agile process. Just one more really difficult thing to put onto your microservices to-do list.
As defined, the Self-Contained Systems architecture is based on separating domain functionality into vertical slices of autonomous web applications, and in essence, creating an integrated system of individual systems. A single SCS contains all user interface, business logic and data persistence to fulfill its particular business case, completely within itself. Each SCS is owned by one team and is individually deployable. Communication between SCSs has to be done in the background, outside of a user’s request/response cycle, and all communication is asynchronous wherever possible, supporting autonomy and decoupling. An SCS must include data and logic, optionally include a service API, and should not share UIs or business code with other SCSs. Infrastructure sharing should also be minimized.
A lot of this sounds like microservices, or at least a best practices prescription for microservices. In truth, microservice and SCS architectures share many characteristics, such as breaking functionality apart, allowing for localized decision making, and decentralized choices for coding languages and database providers. Both espouse building smaller components, allowing for easier replacement. And, both deploy these components individually, allowing for independent scaling.
However, there are several distinctions as well, primarily in scope, sizing and definition. A SCS contains front, middle and back-end elements, where microservices typically focus on a single responsibility. Consequently, a SCS is much larger than a microservice, and there will be far fewer SCSs in your overall system; maybe 5 - 25 SCSs versus 100s of microservices. As for definition, several characteristics have been found in common among microservices, but there are no hard and fast definitions as an architecture. A SCS has the benefit of definition, guidelines and recommendations. To further blend the concepts, if a SCS becomes too big, there’s no reason that its logic layer can’t be further distilled into a set of microservices, providing the best of both worlds.
For me, starting with a loosely connected system of monoliths sounds like a great approach. At my next product start, I won’t know all the intricacies of the entire business domain, but I will at least know that user profile pages have distinct requirements versus content management pages. If the benefits of microservices are my desired outcome, separating out high level business domains before they meld together will gain many of those benefits with less cost. Plus, a SCS should be easier to break apart further when needed. And when I am facing a monolith already, pulling out a larger slice of functionality first, sounds reasonable as well. Take the first cut, iterate agilely, refine the domains as your understanding grows, and if it is called for, split the SCS into two or more, or into a full blown microservices set. Every architecture decision is a trade-off, and depending on your domain, Self-Contained Systems might be the right step on your path to microservices, or possibly the right destination itself.