UI in Microservices World — Micro Frontends pattern and Web Components
The topic of microservices in IT world is still alive. Like every novelty — it makes lots of noise and causes lots of controversies.
Until recently, discussions about microservice architecture referred only to backend applications. Obsolete, disliked and criticized monolith by many, was pushed towards presentation’s layer. At certain moment people started to think — is something not going to explode in a moment?
How should we develop UI in the era of microservices?
Is expanding a concept of microservices to frontend area a good idea?
Are currently used technologies ready to implement this approach?
These questions have inspired me to seek answers on my own. I share the results of my search, my thoughts and conclusions in this article.
Developing presentation layer of modern web applications is not that simple. For many years there’s been the tendency where thin client is replaced with fat client. As a result more and more responsibilities landed on the client side. In the world of microservices, CAP Theorem and eventual consistency, code that makes final decisions more and more often resides on the client’s side.
Why so many new frameworks are being developed? Have you ever been thinking about that?
Maybe it’s because expectations towards presentation layer are getting higher and higher. It is supposed to be faster, nicer, more dynamic, more… But the question is: is meeting these requirements, while applying current approach towards development, still possible?
Thus, perhaps instead of developing a new frameworks, we should focus on making better use of already existing ones? Is expanding microservice approach to presentation layer going to help to meet these requirements?
If we are looking for an answer to questions above, we should be interested in approach called Micro Frontends — techniques and strategies used to create modern web applications which are being developed by many teams which would like to use various technologies.
By extending the definition, we may distinguish the following point in Micro Frontends approach:
- Application, as a set of functionalities, where each one is being developed by independent team;
- Each team has its own business area, for which it is responsible and specializes in;
- Teams are multifunctional (full-stack) and develop their functionalities from start to finish, starting from databases to user’s interface;
- Each team should be able to change technology used.
The illustration above shows in very simple terms what it is all about. On the left hand side we can see Monolith Frontend — huge application using one framework.
On right hand side we have Micro Frontends — small elements which might be written in different frameworks then combined into consistent solution.
It is worth to mention that applying the first approach does not exclude modularity within presentation’s layer. The teams might be divided vertically (responsibility for specific business areas), but they don’t have so much freedom in creating their own parts.
Introducing new approach and bigger freedom might solve certain problems and basically it does. On the other hand, it requires taking certain decisions and meeting several requirements:
- when to integrate particular parts:
- during development
- during runtime on client’s side
- during runtime on server’s side
- during runtime in middleware
- how to design routing and communication between elements/services
- how to provide real separation of elements
- how to avoid conflicts in CSS styles
- how to load elements, only if they are necessary (lazy loading)
- how to share common resources
We are not going to focus on issues above right now, because the way of solving them depends on selected implementation method.
Micro Frontends approach is applied by biggest players in their solutions:
I think that e-commerce branch is the leader in using such solutions not by coincidence. Main functionalities in each portal are well known and defined: search engine, shopping cart, choosing a category, suggestions, promoted offers, ads. Thanks to that they do not change dynamically, which makes it much easier to implement Micro Frontends approach. A separate element, written with using other technology may be responsible for every mentioned functionality. The illustration below explains it on Amazon’s example:
Even though it may be associated with Backends For Frontends approach, these are not identical. For Micro Frontends crucial is composing interface from elements corresponding with different business areas which are supported by various backend services. While in BFF it is first of all about the fact that we develop different interfaces/gateways for various types of clients. Of course, both approaches might be combined with each other. We might have BFF, or other API for mobile application interface, and other for web application interface, while each one will consist of elements.
In the example above, we are dealing with the web client whose frontend is built from a few elements, while each of them has its own UI Composition Microservice assigned.
How to implement microservice approach in presentation’s layer in practice?
- Web Components — they enable creating non-standard reusable elements closed in HTML tags. Theoretically, they work in all modern web browsers and might be used with any framework.
- Project Mosaic — a set of libraries to develop web applications, which use fragment concepts created by Zalando.
- single-spa — an interesting solution with a few working examples. Unfortunately, it is next layer of abstraction in our solution (framework which connects frameworks).
- Allegro OpBox — a solution which is not shared as open source, and won’t be shared until some kind of big player is not going to declare plans to contribution. Still it’s worth reading linked article, because the applied approach is really interesting.
Recognizing the topic and analyzing opportunities above, I’ve decided to focus on Web Components.
Web Components consist of the following elements ( also called specifications):
- Custom Elements, which define how to develop and use new elements of DOM tree,
- Shadow DOM, thanks to which you can hide the details of implementation ( use encapsulations),
- ES Modules, which allow to use earlier defined JS documents in other documents,
- HTML Template, thanks to which we may define fragments which are initiated when they are necessary.
These short definitions may not quite explain what it is all about, which is why I have illustrated them in the examples .
What can we achieve by using Custom Elements — non-standard HTML tags which might be our components?
Currently, our HTML code often looks like this:
Thanks to use of Custom Elements, it may look as follows:
It’s better, isn’t it?
Shadow DOM allows to use encapsulations. Did you know that simple input has hidden two divs in itself?
Normally, we don’t see it, because an option of showing Shadow DOM for standard HTML elements is inactive, but you can activate it very easily in browser options.
According to webcomponents.org website all main four Web Components already work in most popular web browsers:
Web Components — cooperation with frameworks
My next step was checking support of most popular frameworks. I’ve come across a website Custom Elements Everywhere, which tests frameworks in terms of supporting Custom Elements. From most popular frameworks the test have passed for 100%: Angular, AngularJS and Vue. Preact is near (91%), React slightly behind (71%).
Having analyzed the results above, I’ve decided to limit my experiment to Angular and Vue.
In Angular 6 Angular Elements have been implemented. It is the kind of proxy between Angular components and Custom Elements API, which allow to pack Angular component in Custom Element. However, angular-cli still does not support it, and you have to make use of non-standard scripts to deal with it. If someone would like to go deeper into the topic, I recommend great post on Telerik’s blog on which I based myself.
It is worth reading carefully the chapter Hurdles to Production Use, where author describes why Angular Elements are still not suitable for production useand when it may change.
Vue has outrun Angular in this and allows to build Vue component as Custom Element directly from vue-cli. Everything works as it should and there is no problem with that. In built Custom Element there is no full Vue, which involves the necessity to import library separately. Thanks to this approach, components are much smaller than Angular ones — this is a huge advantage.
Bundle size Angular Custom Element vs. Vue Custom Element
I’ve created two components using well-known examples:
I’ve embedded both components on static HTML website:
You can’t even imagine how surprised I was when I had started Google Chrome and saw that it really worked 🙂
Vue Web Components i Angular Elements na jednej stronie
However, that’s all when it comes to good news, because in other web browser does not work.
After added polyfills, Vue Custom Element started working in Firefox and Edge. Angular Custom Element did not working with error in console:
TypeError: r.createShadowRoot is not a function
SCRIPT438: Object doesn't support property or method 'createShadowRoot'
While looking for a solution, I’ve found out that I am not the only person who has this problem and that currently there is probably no good solution.
Apart from testing on static HTML website, I’ve tried to add the components to application developed in AngularJS. Vue component did work without any modifications. With Angular component there were problems related to double loading zone.js. There is a workaround for that, but that is not the way, I guess.
What else can be tested in our PoC?
- different types of communication between components,
- compilers for web component (stencil),
- performance with a lot of components on one website,
- other libraries for Web Components (Hybrids, LitElement, Polymer, Slim.js)
As usual, in questions like “Should I use this pattern/technology in my project?” the best answer is — everything depends on the context.
System architecture is well designed when system fulfills requirements imposed on it.
Micro Frontends approach is surely worth considering with really huge, complex applications, on which work a few teams responsible for different business areas at the same time.
Using this approach raises certain problems which do not occur in Monolith Frontend: additional people responsible for integrating the whole, difficulties in setting global standards or errors, which might cause much more painful consequences in case of monolith.
I think that only the biggest players, whose applications are being developed by dozens product teams, will benefit thanks to the use of Micro Frontends. However, everyone of us should pay attention to the fact that in order to follow modular monolith — divide frontend into small, reusable components/modules which cooperate with each other.
Web Components are already a standard ready to be used, but supporting most popular frameworks still leaves much to be desired.
In Angular, building process is not supported by CLI, bundles are big, because they consist of the whole Angular (it is going to change after implementing the next generation of compilator — Ivy), components, which I have created, worked only in Google Chrome.
In React there is still a problem with more advanced functions, so I skip it in my tests. Perhaps I’ve made a mistake here? If so — I will be grateful for comments with a short explanation.
Vue, which supports the process of developing Custom Elements from CLI, did its best, created bundles are small and work with no problem in most popular web browsers.
If you are interested in, below I share a list of fascinating presentations, websites and blogs which I have used myself.
- Micro Frontend: a microservice architecture from your frontend web apps (slides)
- Micro Frontends: Break up your web app! (slides)
- Micro Frontends: building a modern web app with multiple teams (slides)
- Microservice websites by Gustaf Nilsson Kotte
- Micro Frontends List by Elisabeth Engel
- Front-end microservices with Web Components by Mikki Kobvel
- Compositional UIs — the Microservices Last Mile — Jimmy Bogard
- microXchg 2018 — Micro Frontends — breaking down the last monolith — Matthias Laug
- Michael Geers — Micro Frontends: Break Up You Web App!
- Building web applications with Web Components by Martin Splitt
- The Future of Loading on the Web (Chrome Dev Summit 2017)
- code.talks 2017 — The Recipe For Scalable Frontends (Zalando)
- Micro Frontends Talks Playlist