Let's imagine we're a developer that working in a small startup company that needs an e-commerce like web app to serve the customers. In the early start of our startup, we need to deliver our app as soon as possible to validate the business model and to retrieve quick feedback from our potential customers. So, we decided to start to build the app with this architecture :
This is a very simple architecture and there are only a few members in the teams that working on this app. The front-end and back-end app codebases are managed by a single team for each codebase.
The database shared across multiple APIs managed by our monolith backend that also includes some APIs to integrate with some APIs from third-party companies.
The number of our customers are growing. The business requirements are also increasing. More and more features need to be added to fulfill the customer's needs.
Because the codebase is getting more difficult to maintain and deploy because a lot of new features and functionalities need to added and also a lot of people working on it, we decided to split the monolithic backend to microservices. So this is our current system architecture :
Now, our backend transformed from a single monolith instance become multiple instances of microservice. Each microservice is managed by a single team. They're independent and loosely coupled. Even we can use different frameworks or different programming languages for every instance of our microservices.
And also, rather than using a shared database we decided to use multiple database instances for each microservice. We split the backend into microservices based on the business domain, for example product catalog, transaction, authentication, etc.
If you see the diagram of our new architecture, there is one more node called The Orchestrator that did the orchestration before the front-end can consume it as APIs. For example maybe we can put GraphQL as an orchestrator of our microservices.
We now realize that we have a lot of screens to manage on the front-end side. The number of members in the team that works on the front-end side modifying a single codebase is growing, because the business needs more and more functionalities to satisfy the customers.
After did a lot of discussions there is an idea popped up from one of our front-end team.
How about implementing the same thing as the backend team did on the backend-side to the front-end side?
Is it possible to split the codebase of our monolith client-side app into multiple instances? Just call it micro frontend. Isn't that cool? Because the DDD (Domain Driven Design) a.k.a the microservice is not only for the backend but it could be applied on the front-end.
So we decided to split our monolith front-end codebase, into multiple instances, we called it micro frontend. Right now, our system architecture will be like this :
As you see that now we have multiple instances of micro frontend. Every single micro frontend represents a business domain, just like what we did on the backend side. Every instance of micro frontend is developed by a single team, every instance is independent and loosely coupled.
Even we can use a framework-agnostic approach, it means that we can use different frameworks for each micro frontend instance. Maybe one micro frontend is using React.js and one another is using Vue.js.
Our new system architecture becoming more complex. As you can see that right now we have more than one orchestrator for our microservices, and also we have one more node called Routing to orchestrate and decide which micro frontend that should be loaded.