Recently I was reading "Building Micro-Frontends" book by Luca Mezzalira. It was quite an insightful book with tons of information, the fascinating part was the Micro-frontend decision framework. This post is an abstract of “Micro-frontend Decision Framework” from a few chapters of the book. You'll also find a use case, explaining how to apply this decision framework.
Key Decision Factors
There are four key decision factors based upon which we can make an educated decision to determine how to build a micro-frontend architecture.
- Defining architecture
- Composition
- Routing
- Communication
1. Defining micro-frontend architecture
The first key decision is based on whether we want to render a single micro-frontend per view/page or multiple micro-frontends per view/page.
Single micro-frontend per view is called vertical-split architecture. It should be decided based on business alignment, and how many teams are going to maintain that particular feature. This type of architectural style is suited when one team owns a complete view, it promotes UI consistency.
The second type is called horizontal-split, where there can be multiple micro-frontends per view/page. In this case, multiple teams will own a micro-frontend and will coordinate for any change. This view provides flexibility in terms of reusability.
2. Micro-frontend Composition
This is stitching together to render a complete view. This can happen in three different layers.
1. Client-side - In this case, as the name suggests everything happens on the client side. Where the view is assembled on the client side and served to the customer. For vertical-split architectural style, client-side composition is one of the good options to choose from. Further, there are various types of client-side composition options as below:
a. ES Module - The application can be broken down into smaller JavaScript modules that can be loaded at the compile or runtime as needed.
b. SystemJS - This module loader supports import map specification, this is good when we want to load at runtime.
c. Module Federation - Webpack plug-in used for loading external modules.
d. Web Component - For horizontal-split architecture, web component is a good option. The web component is a custom HTML element, it's a way to create an encapsulated, single-responsibility code block that can be reused on any page.
2. Edge side - When assembling takes place at the CDN (Content Delivery Network) level, however, implementation varies from service provider to service provider like Fastly, Akamai, etc.
3. Server side - The third way to compose the view is at the server side, for example by using a template rule engine like the Freemarker template.
From the above three options, we need to decide on the type of compositions based on the project, infrastructure capabilities, etc.
3. Micro-frontend Routing
Routing is dependent on the type of composition we choose, for example, if client-side composition is decided then routing can happen at the client or edge side. Apart from client-side, and edge-side routing, there is also server-side routing.
4. Micro-frontend Communication
The final one is the communication between micro-frontends, in other words sharing data between micro-frontends. Here is my another post that talks more in detail about different types of communications Ways to communicate between micro-frontends.
Summary
Here is a summary in the tabular format
Architectural style | Composition | Routing | Communication |
---|---|---|---|
Horizontal-Split | Client side, Server side, Edge side | Client side, Server side, Edge side | Custom Event, Web Storage, Query Parameter, Cookies |
Vertical-Split | Client side, Server side | Client side, Server side, Edge side | Web Storage, Query Parameter, Cookies |
Conclusion
There is no silver bullet or one T-shirt size solution to be dictated. A lot depends upon how an organization is structured and, financially and mentally ready to move from a monolithic frontend to a micro-frontend architecture. It's always going to be trade-offs (as the first law of Software Architecture says “Everything in software architecture is a trade-off.”), some of which may work for some cases but won't work for others. Here is a sample use case along with reasons behind why it was selected (as stated in the second law of Software Architecture, “Why is more important than how.”).
Use Case
Statement
Let's say we need to migrate a monolithic frontend e-commerce app, which consists of a header, item catalog, and quick checkout on a single page.
Background
The two features item catalog and quick checkout will be owned by two different teams. Also, the header needs to be reusable components, going to be owned by a separate team. The header will be needed across legacy and modern tech stacks. So altogether 3 teams will be involved in the development effort. ReactJS will be used for all micro-frontends and Webpack will be used for JS bundling.
Applying Decision Framework
Starting with the first key decision factor, for this use case horizontal-split is a better suitable option, the reason behind choosing horizontal-split is that there are multiple teams involved in a single view.
Next up is composition, here client-side composition is going to be a good choice, the main driving factor here is the type of technology going to be used to develop the micro-frontends, ReactJS in this use case. Going one step further, application shell will be rendering the complete view. Module federation can be used for item catalog and quick checkout micro-frontends to load the modules on the runtime as anyways Webpack is already used for JS bundling, whereas, the header can be a web component along with SystemJS module loader as the header is needed to support the legacy and modern tech stacks.
Next, we need to decide on type routing, as mentioned before routing depends on composition. As client-side composition is chosen for this use case, for routing we are left with either client or edge-side routing. As the edge is CDN (Content Delivery Network) service provider dependent and may not be suitable for multiple CDNs or later migration to new CDNs. Hence, client-side routing is a better option.
The fourth and final factor is the decision on communication. In our use case, the only time when the item catalog micro-frontend needs to communicate to the quick checkout micro-frontend is when some item from the catalog is added to the cart. We can use web storage and cookies, just keep it simple cookies can be used.
Well! that was quite all about micro-frontend decision framework.
If you have reached here, then I made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or ask for any corrections.
Top comments (0)