We’ve done SOA, why should we care about Microservices?
When talking to IT managers and Enterprise Architects on the subject of Microservices I sometimes get asked what the difference is between Service Oriented Architecture (SOA) or Microservices Architecture (MSA), and which is better. Both architectures are similar in the sense that they concern the development of systems through (published) services, so the question is not unfair. Another way the question may surface is: “If I have a Service Oriented Architecture and make my services small, does that mean I am doing both SOA and MSA?” In this blog we’ll discuss the business problems they try to solve, and from that show the –sometimes fundamental– differences in their impact on the organization.
SOA and the Reuse of Services
When the concept of a Service Oriented Architecture was launched, the idea was that if you build a service that provides a common function, it would be a waste to keep it from others in the organization. The underlying premise is that writing software is expensive, and multiple implementations allow for different interpretations of what actual service should be provided. By making your services available to the entire organisation you get a single source of truth, and nobody needs to re-invent wheels. As such, SOA is a lot about responsibilities and where they lie in the organization, rather than things like application size and the technologies used. Also, the cost aspect tends to be stressed as an advantage of SOA, even though it may lead to limited development flexibility due to the need to conform to (potentially) another department’s choices.
That said, “doing” SOA has become synonymous with the use of communication protocols like SOAP (the Simple Object Access Protocol) over HTTP, tools like an Enterprise Service Bus, and messages encoded in XML, all of which has little to do with organizational structure, and everything with technology. Looking further along those lines, you could say that Service Oriented Architectures led to the popularization of “Middleware” as a separate layer, and products targeting it became powerful platforms for application integration. It also helped cement the importance of “Enterprise” standards, most notably centralized data dictionaries and Enterprise Architecture.
Now, if we have a central location where all services are registered, service clients need no longer worry about how to find them, nor how to communicate with them. So how is that wrong? The problems arose from having a pivotal element in your application design “poured in concrete.”
Supporting change around a fixed element
With application development you will soon be confronted with the need for change; either the “customers” want a slightly different service interface, or you yourself want to incorporate new functionality and lessons learned. This causes friction, because you can no longer consider the service interface as fully your own, and unexpected (from the viewpoint of the users) changes may break other applications. You are left with basically two alternatives: create different versions of the interface, or coordinate releases over the boundaries of applications or even departments.
Versioning of services may come in the form of the Facade pattern, putting a thin layer with an alternative interface in front of your service, the Adapter pattern, which puts the changed layer near the client, or evolutionary versions, where you talk about the “new” and the “old” interface. Platform solutions such as the Enterprise Service Bus soon targeted this problem, allowing you to quickly develop variations on services, but also use service composition and create aggregated interfaces. You create the basic service once, and then implement the variations in the ESB. The Middleware layer, sitting in-between services and their clients, grew with the addition of increasingly complex compositional technologies, allowing automated processes to use a high-level “script.” (BPEL and -later on- BPMN if that means anything to you) All of these with glorious amounts of XML, consuming and producing SOAP services. As a result we have a feature-rich and highly volatile interface layer with actual business functionality in it, which often prevents development agility for the back-office applications through the rigid interface specifications. Where it does support agility, is in the Middleware layer itself, either duplicating business functionality, or else creating confusion around business ownership of that functionality. Before long the middleware layer is a more important platform than that of the back-office applications.
At the core, the problem is one of apparently conflicting goals: combining high-quality software with a quick time-to-market. The first forces IT into using strict rules on development practices, while the second searches for ways to circumvent those rules. At the same time, both goals clamor for high levels of reuse to reduce cost. Unfortunately, the most important effect of chasing reuse in the context of strict specifications and high-productivity platforms, is that all applications are increasingly tied together into a giant ball of mud. No application can be changed without implications to many others, and release cadences of once per four months (or slower) have become the norm in many large organizations.
Now turn it around: change as the only constant
While the business grew increasingly frustrated with IT’s inability to quickly provide new or adapted functionality, IT grew increasingly frustrated with a steady stream of seemingly uncontrolled apps of dubious quality that the business kept throwing at them. The Agile Manifesto was conceived to overcome this problem, advocating to take small steps, release after each small step, and then seriously consider if you’re still going in the right direction. Naturally neither side thought the other could ever do this right, and both would love to do it. But the thing is: there still is this big ball of mud in the room, and it has Elephantal proportions. How can you introduce the speed Agile development methodologies promise, without having to redo everything. (or at least; that big elephant)
The only way to solve the problem, is to put the focus on where the problem originates: not in the way either Business or IT needs to change, but in the way they don’t cooperate enough. IT originates in office automation, and as such has always been classed as a cost centre; a department that requires investments, but basically only exists to serve. Money is made by the Business departments, using IT services, and this has led to the culture of IT project management, where applications are delivered as “the product” and sourcing becomes a viable discussion just as for laptops and phones. Lean Software Development shows that this inevitably leads to business failure, as constantly changing market demands with an increasing impact from the use of IT technology, don’t mix well with an externalized IT process. Just like the development of a new car, this only has a chance of long-term success if marketing, sales, and production work as one team, and the product is the thing you sell to customers, not the thing you use to produce it with.
Microservices Architecture as a consequence of Business Agility
Now we have a clear view of the origins and goals of Service Oriented Architectures, which fails more often in execution than principles, how is a Micro-Services Architecture different? First of all we need to understand how Lean and Agile Software Development have taught us that we can only expect to get a fair chance at success if we start seeing change as a continuous stream of small steps. Software Development is one of the few disciplines where every undertaking targets something not seen before. If it weren’t, we would just make a copy and be done with it. At the least it will be a new combination of goals separately achieved before, but more often we’ll also have to deal with some platform or technology (used or targeted) that has changed, integrations that have shifted or transformed, and new or changed business requirements that need to be taken into account. As a result we have a high level of so-called “essential complexity”, which is a nice term indicating that we have to deal with complexity that we cannot go around, and cannot fully fathom until we start tackling it. Just as with R&D, the first time you do something you’re experimenting, the second time you’re learning, and only the third time you can seriously start automating.
The only way you can tackle tasks with a high level of essential complexity is by breaking them down into small pieces. This is comparable with making a Work Breakdown Structure from Project Management lore, but the difference is that the unknowns in the smaller steps (and most of them will be “unknown unknowns”!) will affect the whole breakdown structure. So you have to select the most important part, and put your focus there, or, as Jez Humble, Joanne Molesky, and Barry O’Reilly put it in “Lean Enterprise”: “biggest pain first.” Don’t waste time on detailing the non-essentials too much, as you may need to redo it, or even skip it completely. Then make the details into small and comprehensible “stories” that you can estimate accurately. The bigger pieces you can prioritize for follow-up, but estimating them is likely wasted effort.
This is all you need to know about “Agile Software Development”: determine in what direction you want to go, take a small step in that direction, and then re-evaluate. You can apply this to any software architecture you want, but you’ll find in the long run that it works best if your size of deployment is relatively small. “Agile” will give you the agility needed to adapt to a constantly changing environment, but if the application is a ball of mud, you will find the steps getting smaller in useful change, while increasingly time is needed to “refactor” the application around it. What Microservices Architecture does is simply stating that your size of step should ideally be your size of deployment. Don’t worry about “micro”, that term must be seen relative to the big ball of mud. Furthermore, if you are able to make the pieces of your application essentially ignorant of how they need to communicate with the pieces around them, you can create a buzzing cloud of busy bees, each performing some seemingly independent task, but together achieving great things.
Domain Driven Design and Autonomous Components
Microservice Architectures are certainly not without their own challenges, especially if you consider the explosion in independently moving parts it will give you. What you need to look out for however, is focusing on the technicalities of it. Remember, just as SOA was about organizational structure rather than tools and standard protocols, microservices are about business agility rather than –again– tools and standard protocols. Domain Driven Design (DDD) helps us get the focus right, by introducing the concept of a “Bounded Context”. Communication within a bounded context serves that context, so it should not be exposed to the outside world. The context as a whole might use an entirely different vocabulary when talking with the outside world, just as your business departments selling products use a different language than the accountants working on taxes, even when they discuss the same concept: money.
Bounded contexts give you natural boundaries along which you can provide components with the needed autonomy. I don’t want to force an accountant to use the same applications as I am using for building software, even if we both talk about “buying”, “selling”, and “profit”. But we can find a middle ground in how we exchange information. Within our respective domains we will likely use entirely different terms to refer to the same concepts, or we may collectively refer to several concepts with a single term, where that grouping would be nonsensical in the other domain. Giving the domains maximum autonomy gives each their needed agility, to build or buy as needed. For each domain we can also tie costs and profits together, and stop the artificial division between business and IT. Trying to save money by reusing applications across domains will tie those domains together, and eventually become a hindrance. Using a bookkeeping application to register consultancy hours doesn’t make sense, and will thoroughly frustrate the side that lost its own domain language.
Conclusion: don’t choose up-front; evolve!
Hopefully you will not be surprised when I conclude that choosing between a Service Oriented Architecture and Microservices Architecture, or even talking about their differences in application design and implementation, is nonsense. Going back to their roots it becomes immediately clear that you cannot simply choose between solving application ownership issues, promote reuse, or improve business agility. All of these are important, and all can profit more from adopting Domain Driven Design than choosing a single architectural style or powerful new technology.
If you are so lucky that you can start with a clean slate, don’t fall into the trap of a Big Up-front Design, even if it calls for a Netflix-style microservices architecture. Set boundaries around business domains, and solve problems on a local scale. Don’t be afraid to start with a monolith, but expect to refactor, and prevent choices that make refactoring slow or expensive. Using CQRS and an event driven architecture with the Axon Framework allows you to promote autonomy for your application components, and keep your developers happy and productive. If you follow the path of DDD, and manage to prevent or “strangle” the monolith, don’t worry about the size of your components. Worry about your agility first, and if that prompts you to strive for small, independent components, welcome to the wonderful world of MSA. Don’t be surprised when you discover that you’ve thus walked “the Way of the Microservice.”
Axon Framework is an open source Java framework for event-driven Microservices and Domain Driven Design. Axon Server is a zero-configuration message router and event store for Axon based application. You can download the quick start package here.