Microservices - Advance at Your Own Peril

Imagine you're at a buffet, and instead of having one giant plate of food to juggle, you're suddenly handed a tray with a dozen tiny appetizer plates. Welcome to the world of microservices, where we've taken the 'divide and conquer' approach to software architecture to a whole new level. While it might sound like a fantastic idea—after all, who doesn't love bite-sized treats—there's more to these miniature marvels than meets the eye. In this ride through the cons of microservices, we'll explore the ups, the downs, and the occasional crumb that might just make you reconsider if you're truly ready to dive into this deliciously complex world. So, grab your fork (or maybe a network cable) and let's dig into why sometimes, less isn't always more!

The Driving Force: Why Microservices?

So why are you considering microservices in the first place? I can anticipate the answer already, “bEcAusE scALaBiLiTY”, and while I might be mocking you now, there is some truth to this, but the thing; is the kind of scalability that permits microservices is nowhere near the bar people usually hit when they think “I know! I’ll do microservices!”.

Common goals to implement microservices (pause here; can I stop saying microservices? because they’re not so micro, and to be honest it’s hard to keep typing again and again, instead, I’ll use SOA which is more accurate and stands for Service Oriented Architecture) are scalability, agility, technology diversity, resilience, fault isolation and some more, but in all conversation I’ve been through with someone wanting to implement SOA, the main driver is scalability.

Of course, scalability comes in many shapes, there’s codebase scalability, team scalability, and service scalability, and to be frank, SOA does solve all of these problems (Fantastic!), but also to be frank, you’re probably not at the scale to benefit from SOA yet.

I see you’re dead-set on implementing it, so let me try to convince you otherwise, first of all, the complexity of implementing a proper SOA is 10x what you’re imagining it is, and if you think otherwise, you’re either delusional or have never implemented SOAs. Everything is suddenly more complex; You want to track an issue? Sure, let’s try to make sense of a request that hoped through 7 hoops and back, assuming of course that you’ve implemented infrastructure to gain visibility on what’s happening to a single request through all your services. You want to implement a new feature that requires a breaking change to the API? Sure, let’s just coordinate the change between these 4 services. Did I mention you need to deploy them all at the same time? You want to apply “a song from every region” to your tech stack, eh? Now you’re using some stack that only a couple knows in your company and when those leave, let’s hope you’ll find good engineers to fill their shoes. I hope you see where I’m going with this. Implementing SOA with a small team (less than 50) of engineers is crazy hard and rarely reap the benefits.

Is SOA shit then?

The Elden Path and the Majestic Monolith

Certainly, not. However, in most cases, it's akin to using a jackhammer to crack open a peanut shell. So what are the reasons for implementing SOA?

In my view, if you encounter one of these scenarios, then maybe you should consider SOA. Even then, less drastic alternatives might be available.

Team Size

The primary factor signaling the need for division is typically team size, which correlates with codebase size and the app's complexity. If your app has grown so substantial that a handful of engineers can't fully comprehend it (tip: capable engineers can surprise you with their codebase mastery), then SOA might cross your mind. An essential caveat here is that you don't want all engineers handling all services collectively; you want dedicated teams for each service. That's the bottom line—if your team can't afford to fragment and devote themselves to individual service teams, you might be jumping into this prematurely.

Non-SOA Solution: DDD (Domain Driven Development).
You can certainly take steps to facilitate this division. DDD is a popular approach, but a caveat to consider is that to gain maximum benefits from DDD-driven service splitting, you'll need clear boundaries between services. They should communicate via defined APIs (not to be confused with HTTP APIs) and never through direct access. This way, when you decide to segment a domain into a service, you only need to modify this layer. Instead of directly interfacing with a class, your code interacts with an external API that represents the hosted service. This approach shines in cases where the app is substantial and encompasses several well-defined domains.

Differential Complexity

If you have a part of the app, that its stack requirements are drastically different, then you might consider splitting this part into a service. For example, if your Laravel app is doing some heavy video manipulation, you’re better off with something dedicated to this specific task, so you might create a service that runs on a beefy GPU-accelerated box to process the files using FFmpeg.

Non-SOA Solution: Serverless Functions
Even if you do have differential complexity, consider building a serverless function that does the specific task at hand and that’s it. So in the example above, your app might save the video file to central storage, and invoke the function, the function reads the file from storage, process it and save it somewhere else.

Should You Implement SOA?

“It depends”. But for most apps I would say it’s an overkill. My recommendation would be to go simple, unless absolutely necessary, leave SOAs as a last resort because I promise you it’s a costy and dangerous path.

Till the next one. Stay Simple 🤙🏼