The Microservices and Microfrontend Mindset: Think Decoupled

  You block advertising 😢
Would you like to buy me a ☕️ instead?

For the last couple of years, microservices and, to a lesser degree, microfrontends have been all the rage when it came to building new software systems. However, although microservices promise vast benefits over traditional monolithic approaches, in many projects, those didn’t materialize. More and more people talk about returning to a more traditional, monolithic architecture and are happy with it. Why is that?

I think there are effectively two major reasons for this:

  1. Whenever a new technology is hyped up, we tend to overuse it. In short, many projects started migrating to a microservices-based architecture, although they shouldn’t have because they don’t face most of the problems this pattern aims to alleviate.
  2. Architects, managers, and developers did talk a lot about micro this and micro that, but they ended up building distributed monoliths featuring the worst of both worlds.

As a community, we quickly changed our talk but didn’t change much how we think about solving problems.

Distributed monolith: frontends and services all depend on concrete implementations of each other

Frontends and services all depend on concrete implementations of each other

If you can’t work on your microservice or frontend locally without spinning up other services, you’re probably not getting many of the benefits you hoped for. You end up in a situation like the above graphic where, as a developer, you have to spin up the entire web of dependencies just to work on a tiny “micro”frontend. However, an effective microservice or frontend must be perfectly decoupled from other system pieces. Yet, it isn’t if you can’t run it locally without spinning up any other services.

If you can’t work on your microservice or frontend locally without spinning up other services, you’re probably not getting many of the benefits you hoped for.

Let’s explore how we can do better!

Talking Differently but Not Thinking Differently

During the great microservices hype, development teams promptly started to draw architecture diagrams, prefixing all their modules with micro this and micro that, microservices here and microfrontends there, but didn’t fully appreciate what a paradigm shift like this entails.

We often ended up in situations like this:

A single user story implemented by a developer leads to multiple pull requests in multiple services

A single user story implemented by a developer leads to multiple pull requests in multiple services

Many companies started to create dozens of repositories for projects that, as we later realized, often have to change together. We were very quick to split up our codebases, not thinking much about how various pieces can or can not deliver value on their own. Furthermore, we completely ignored our giant 20-year-old database, which is almost impossible to split up, at least not in the foreseeable future.

The hype seduced us, and we rushed to action, not thinking much about the consequences and what else had to change apart from splitting up our codebases. The only thing we could think of was what we soaked up watching some conference talk about how Netflix does it, the promised land of independent deployments and product teams.

What we didn’t do was to change how we think about building software altogether. We didn’t update our mental models, viewing our software systems not as one large piece delivering a large chunk of value but as a web of small pieces, each independently delivering smaller chunks of value.

A big software system delivering a big chunk of value

A big software system delivering a big chunk of value

A lot of small pieces each deliver value, the sum of all parts is greater than the whole

A lot of small pieces each deliver value, the sum of all parts is greater than the whole

Think Decoupled

Building microservices- and microfrontend-based systems requires us to update our thinking, significantly changing how we think about and build our software.

We must view each microservice and each microfrontend as a truly independent module that doesn’t rely on any particular implementation of a service or other microfrontend. Sure, a specific microservice might depend on the functionality provided by other services. But there is an important difference between depending on a particular microservice and depending on the functionality the microservice provides. It’s similar to code depending on a particular implementation versus an interface. We must build our microservices and microfrontends as if they depend on interfaces, not concrete services.

There is an important difference between depending on a particular microservice and depending on the functionality the microservice provides. We must build our microservices and microfrontends as if they depend on interfaces, not concrete services.

Our goal must be to build frontends and services relying on the specifications of the capabilities of other services and not their concrete implementations. We need to build genuinely decoupled services.

We can achieve proper decoupling between services by following approaches like API first, relying on writing API specifications using OpenAPI before writing code, and tools like Specmatic.

The developer in the following graphic can work truly independently of any other service:

Building against specifications instead of concrete implementations

Building against specifications instead of concrete implementations

Following the API first approach and building our applications fully decoupled, only relying on specifications of other services, is a sign that we’re on the right track, not only talking microservices but thinking and practicing microservices.

Only when we build our services and frontends relying on specifications instead of concrete implementations can we work genuinely independently of other services and teams and can we build and test our applications isolated from the rest of the system and benefit from fast CI/CD pipelines. Only when we think decoupled do we get all the benefits of microservices-based architectures.

To deploy microservices effectively, we must adapt our thinking first. We must start thinking decoupled, as if we didn’t know anything, apart from their (OpenAPI) specification, about the other pieces of our system.

Wrapping It Up

We must think differently to act differently. When the only thing we do is to talk differently, prefixing all our modules with micro and splitting them up into separate repositories without giving it much thought, we head for catastrophic results. We probably end up with all of the drawbacks of microservices, of which there are quite a few, and none of the benefits.

First, think differently, then act differently!


Do you want to learn how to build advanced Vue.js applications?

Register for the Newsletter of my upcoming book: Advanced Vue.js Application Architecture.



Do you enjoy reading my blog?

You can buy me a ☕️ on Ko-fi!

☕️ Support Me on Ko-fi