5 minute read

What I find so attractive about microservices is that they provide a way of realizing long-sought principles and practices of software development by using lightweight, but powerful tools. This grounding in widely accepted best practices without many of the compromises or heavy up-front investment, required by approaches of the past, means you can approach them incrementally and with confidence. “Betting” on microservices is very different than bets of the past like J2EE or RUP (tool heavy, vendor defined) or ESBs (product-bound). Betting on microservices is kind of like betting on building something the way you’ve always wanted to.

The following are some of the principles that microservices move us closer to realizing while building complex scalable solutions, often atop an existing technical landscape.

Any non-trivial program contains at least one bug – Anonymous

The corollary to this is then to reduce the number of potential bugs you increase the triviality of the program. While microservices are not trivial programs, the fact that they are autonomous and scoped to a bounded context within a domain means that they are more trivial than software that is either not autonomous (directly coupled to many systems) or not operating within a well-defined scope.

Software architecture is those decisions which are both important and hard to change – Fowler

I love the definition of software architecture as decisions that are important and hard to change. The implication then is that when you create adaptable systems (i.e.: those that can be easily changed) you want to limit the number of architectural decisions. The overarching “architecture” of a microservices-driven system is very simple: clear contacts and simple messages atop which strategies and patterns are applied on an as-needed basis to model more complex processes.

The strategies and patterns used for complex processes are local to the process. For example, when we decide to use a Routing Slip for a message that must follow a specific processing sequence, we’re not saying that all services must communicate using Routing Slips. We apply what we need to, when we need to, to the job at hand, and allow others the same freedom.

The autonomy of each microservice means that what architectural decisions you do make are local to the service. In systems with non-autonomous (interconnected) components, architectural decisions are very difficult because of the wide-ranging implications of those decisions – this also makes the decisions much more permanent. Because each microservice can have its own architecture, you can be much more brazen and opinionated (which generally leads to simpler software and less code), and if you get it wrong, the smaller scope of the service means you can change it much more easily. In fact, based on our definition of architecture (important and hard to change), we aren’t making architectural decisions.

Domain-Driven Design – Evans

Domain-Driven Design is an approach to building software that requires a shared understanding between the engineering team and the business it supports. The benefit of domain-driven design is that your software is well aligned with the business and is easy to change as the business evolves. The drawback is that domain-driven design can be difficult to achieve, particularly when much of the domain is supported by third party monolithic enterprise systems that often force you to use their domain to describe your business. Add to that the point-to-point integration patterns that bind and bleed systems together, and not only have you forsaken domain-driven design, your IT landscape becomes increasingly rigid and difficult to change.

Even if the systems and business were aligned at one point, business is constantly evolving, and rarely does the path of the business’s evolution match the path of the systems you’ve integrated. As the gap between the system and the business increases over time, the software you’ve invested so much in to try to enable the business becomes widely viewed as an encumbrance.

The foundational principle of microservices is that they be domain defined, and what tooling exists is in direct support of being able to define the services quickly and easily in your domain language. The integration patterns of the microservices architectural style creates space for the domain to thrive, decoupling legacy systems with business defined contracts that help maintain the agility of your IT landscape. As Evans states, “Domain-driven design is a difficult technical challenge that can pay off big, opening opportunities just when most software projects begin to ossify into legacy”. Microservices provide a well-defined means of addressing the technical challenges while delivering the benefits of domain-driven design.

Inherently Agile

As an industry, we have become very adept at “doing agile” without “being agile”, meaning we follow some methodology and do stand-ups and have a backlog, but we produce processes and systems that are slow and resist change. There are many reasons for this, but microservices provide a way of realizing the promise of agile: to be able to move quickly and easily.

Because the scope of a microservice is defined as a bounded context within a business domain, the software team must include substantial business representation. Without the business, there is no domain to represent and the service has no purpose. As the microservice is clearly bounded, it can be typically be worked on by a small (5 person/2-pizza) team. As well defined microservices are autonomous, the team can truly own the service and make many of the decisions about how the service operates.

What I’ve laid out is at the very heart of agile: a small team with a clear sense of ownership and a clear purpose. It’s the conditions under which we can progress through the cycle of forming, storming, norming, performing. It’s what Daniel Pink defined as motivation: autonomy, mastery, purpose.


“Microservices” is working its way through the hype-cycle like so many ideas that have come before it, but it’s important to recognize the pedigree of the foundational concepts. Microservices are just services: defined by the domain they serve, scoped to a bounded context within that domain, and autonomous. They are what we as software developers and engineers have been desperately trying to build our entire careers, and now the barrier to entry is sufficiently low that we might just get the chance.