Somebody call the buzzword police: we have a serious case of microservices-washing in progress. The term "microservices-washing" is derived from "whitewashing," meaning to hide some inconvenient truth with bluster and nonsense.
We saw plenty of cloudwashing a few years ago, as vendors and enterprises alike pretended what they were doing was cloud, even though it wasn't. Today, the hype around microservices has led to the same kind of obfuscation, as vendors and enterprise technologists alike are saying they're building microservices—even though a cursory look at what they're really up to wouldn't uncover a single one.
Only by stripping away the hype of microservices-washing can vendors and practitioners alike garner the true value from microservices.
If Not Microservices, Then What?
The notion of a service as a way to expose a software capability came into its own at the beginning of the century with the rise of web services. Fed up with the inflexibility and tight coupling of CORBA (Common Object Request Broker Architecture), the vendor community hammered out a set of XML-related standards for implementing software interfaces that abstracted the underlying implementation of software endpoints.
Until the rise of microservices, in fact, the notion of a service was a software interface. Vendors loved this definition, because it allowed them to create their own proprietary execution environments to add to their middleware offerings, renaming them enterprise service buses (ESBs).
A microservice, in contrast, is a parsimonious, cohesive unit of execution. It's decidedly not a software interface itself, although it obviously has one. Instead, at the heart of the microservice is the running code itself. Microservices also contain their own runtime, so they don't need to run on an ESB.
This distinction goes to the heart of the microservices-washing epidemic, because what it means to build, run, and integrate a service is entirely different depending upon whether the service you're referring to is a microservice or a web service.
The Vendor Microservices-Washing Trend
Vendors have struggled with the services story for years, because it didn't take long for all the buzz around web services to shift to service-oriented architecture (SOA). And in spite of all the millions of dollars vendors sunk into their SOA messaging in the last decade, one simple fact always tripped them up: SOA is something you do, not something you buy.
Today we're seeing the emergence of microservices architecture. It's not fully baked yet, but it's mature enough to be able to tell that while it inherits some of the basic principles of SOA, it's fundamentally a different set of practices—because the entire environment has completely transformed.
The environment for SOA was enterprise IT of the 2000s: plenty of legacy, heavyweight middleware and a diverse range of applications running across the company. The environment for microservices architecture, in contrast, is the borderless enterprise: end-to-end, cloud-centric digital applications leveraging fully virtualized infrastructure.
For incumbent vendors—that is, those software companies whose products matured during the SOA days or earlier—this new world promises to disrupt their entire product line. In order to survive, they will essentially have to rewrite all their software. To be fair, many of them do have such a reinvention in progress.
Their marketing folks, however, don't like to wait. They want to jump on the microservices bandwagon now. Perhaps their products actually have a few microservices under the covers, but who knows? Saying you're "microservices-ready" or "built with microservices" is vastly different from offering software or software-based services that are full-fledged participants in the new borderless digital reality.
Microservices-Washing in the Enterprise
You implemented SOA in your organization back in the 2000s, and you still have a number of production web services to show for your troubles. Should you turn them into microservices?
Probably not. After all, if the services you have in production are still working and providing value, then the fundamental principle you should follow is if it ain't broke, don't fix it. Instead, what many architect teams are doing is renaming those legacy services "enterprise services."
They may be web services, or perhaps you implemented RESTful services back in the day. Regardless, if you already have services in production whose primary purpose is to expose legacy application functionality or data, then reworking them into microservices is unlikely to be worth the trouble.
That being said, the reason you may be tempted to change out these enterprise services in the first place is that they aren't adequately addressing current needs. When you analyze the problem, you'll likely find that it boils down to the fact that they're too big. They're trying to do too much, and thus, not doing much of anything very well. And since microservices are supposed to be parsimonious, perhaps they're just the ticket.
Not so fast. The principle of parsimony—that microservices should be as small as possible but no smaller—applies to the code that makes up the microservices. But remember, that big old web service that's giving you so much trouble is a software interface. And while there's certainly code under its covers, when we say a web service is too big, we probably mean it has too many operations.
Web services came in two basic flavors: entity services and task services. Entity services represented business entities analogous to the way objects represented such entities, where the service's operations represented things you would do with the entity. For example, you might have a customer entity service, and its operations might be createNewCustomer, changeCustomerAddress, authorizeCustomer, etc. And the more things you might do with customers, the more operations you'd have—sometimes dozens or even hundreds of them for a single entity service.
Task services, in contrast, represented a single task. In other words, they had a single operation, or you could even think of the entire service as the operation.
Each type of service had its strengths and weaknesses. Entity services had more of a business context, but they were less flexible and difficult to compose. Task services were easier to compose and update but often lacked a clear business context.
Because task services are parsimonious, they resemble microservices. In fact, we might consider a microservice interface to be a task service, but the reverse doesn't hold. Just because a service is a task service, that doesn't mean it's a microservice. That's where the microservice-washing comes in.
Most enterprise services are actually entity services. If you have an enterprise service that's an entity service, and it's not meeting current needs because it's too difficult to update, the solution is more likely to rework it into several task services on the ESB that supports the original service, rather than try to reimplement it as a microservice.
In other words, microservices aren't always the best way to solve problems with older services. Unless you're moving your service infrastructure to the cloud, expecting to reimplement existing services as microservices is just asking for trouble you don't need.
When to Consider Microservices
When you're ready to branch out from the traditional middleware-driven SOA stomping grounds and build new cloud-based application functionality, then microservices should at least find their way onto your roadmap. If you're implementing containers, then microservices suddenly become the default choice.
Microservices don't require containers (or vice versa), but they're easily containerizable by design. Furthermore, if you're implementing containers, it's difficult and typically unwise to put any new executable code other than microservices in them.
But if the services you already have aren't easily containerizable, then they're either poorly implemented microservices or perhaps not microservices at all. But don't microservices-wash them. Instead, have your microservices interact with them as part of a microservices data layer.
Back in the SOA days, we built data service layers by implementing web-services-based data services that exposed legacy data create-read-update-delete (CRUD) queries as web service operations. Today, we can use microservices to abstract such data services as RESTful resources, where individual microservices respond to RESTful calls by abstracting underlying CRUD operations.
The decision whether or not to implement a microservices data layer, of course, is an architectural one, and furthermore, a service-oriented architectural one. SOA, of course, hasn't gone away, but it hasn't stayed the same, either. Therein lies the true lesson of microservices-washing: to get microservices architecture right, we must keep some tried-and-true SOA practices while adding new ones—a challenge that requires a reasonable level of architectural maturity. There are no shortcuts to good architecture.
Now that we understand how to architect for the cloud and now that microservices architecture and containers are on our roadmap, it's time to update our SOA books for a new generation of architecture—no microservices-washing allowed.