Microservices, Self-Contained-Systems and DDD
I had the opportunity and pleasure to attend to this year's Software Architecture Summit in Münich. It was a great conference with great speakers. The focus this year was logically on Microservices. This new buzzword seems on the first glance to reveal some brand new principles…. But as heard at the conference and summarized here, it is in fact only a straight forward continuation within the approach of modularizing and decoupling software systems.
Looking for a definition…
So what are Microservices all about? What is the difference between Microservices and Self-Contained-Systems, how do these two architectures differ to SOA? What are the benefits and the challenges that these architecture approaches bring along?
All in all, the concepts behind these new architectural approaches are nothing brand new – they are absolutely in line to what is going on in software-engineering since very long: it is all about modularization of the software and setting the focus on a separation of the functionality into many independent systems, making the complete logical system a collaboration of many smaller software systems. The ultimate objective relies in the strong belief, that one finally gets a good chance to avoid the problems of large monoliths that grow constantly, do not scale as expected and eventually become unmaintainable.
Although experts disagree on the question if Microservices and SOA have at all things in common, let me share here the optimistic idea that Microservices may finally be considered as "service orientation done right".
Looking for a definition for Microservices, Martin Fowler and James Lewis suggest the following characteristics of Microservices architectures:
1. Componentization via Services (rather than Libraries)
Leverage the advantage that Services are independently deployable and build therefore better modules/components.
2. Organized around Business Capabilities
Remember Conwey's Law: "Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.", Melwyn Conway, 1967 It is recommended to consider the organization structure while modularizing your overall application landscape.
3. Products not Projects
Prefer self-responsible teams which cover full product responsibility up to successful operational software over teams which are disbanded when a project is delivered. Refer for example to Amazon's notion of "you build, you run it"
4. Smart endpoints and dumb pipes
Prefer simple messaging over complex and smart routings and orchestrations (for example via a very smart ESB). Host instead business complexity within smart endpoints/services.
5. Decentralized Governance
Take advantage of the technical expertise of your teams. Let the teams choose their best technological fit. Do not try enforce single-technology platforms which are meant to solve this and any problem.
6. Decentralized Data Management
Realize that the views differ depending on the business perspective. Reflect this differences in the domain boundaries you define. Prefer multiple decoupled persistence units than one big datastore (see also later described shared-kernel).
7. Infrastructure Automation
Nothing brand new here: Infrastructure Automation is final about getting to Continuous-Delivery.
8. Design for failure
Consider failure not as an exception but as granted case. Do not try to repair on failures but try instead to build failure tolerance.
9. Evolutionary Design
Only through a modular design, one gets the chance to evolve design so that – with the time - the impact of changes becomes more and more granular and specific to single modules.
Those characteristics surely also applies to Self-Contained-Systems (SCS). Still, a definition provided by the scs-architecture-board suggest a set of even more specific properties:
1. An SCS is an autonomous web application.
2. An SCS is owned by one team.
3. The communication with other SCSs or 3rd party systems is asynchronous wherever possible.
4. An SCS can have an optional service API.
5. Each SCS must include data and logic.
6. An SCS should have no shared UI with other SCSs.
7. An SCS should share no business code with other SCSs.
8. To make SCSs more robust and improve decoupling shared infrastructure should be minimized.
According to this, one can conclude that SCS and Microservices share the same core architectural concepts. However, they differ in the restrictiveness of their definition: Microservices are undefined about the artifacts being a web-application or just another kind of web-aware service. Also – even if most of the characteristics of SCS surely can be taken as design recommendations for Microservices – these constraints are effectively not formally written down for the latter.