Backend developers are a bit like ”The Simpsons” TV show — whatever you think of, the Simpsons already did it. React server-side rendering was a thing a few years ago. So what? Java had it at least 15 years earlier. Reusable components? Yawn, old news for the backend. Reactive programming? Backend already did it!
Well, one of the problems that have been a pain in the back for the frontend developers was the monolith app architecture. Backend, as you might imagine, already did it some time ago by introducing the microservices architecture. It’s been around for around 15 years and it seemed to be a worthless technique for the frontend, but is it really? Enter micro-frontends!
What’s the hassle all about?
First of all, what do we mean by micro-frontends? Most simply put, it’s when an application consists of at least two components, which could serve as standalone apps themselves. This could be, for example, keeping all of sections of a website: the header, the search component, the component showing navigation and the one displaying the content could all be different applications — developed, deployed and maintained separately.
In another scenario, an application could consist of multiple standalone views joined with micro-frontends to create a portal application. Note that this approach gives you an opportunity to separate the domain from the actual underlying application — views from different apps can be mixed across different sections of the portal app, as long as it makes business sense.
It also makes a lot of sense to combine those two approaches and integrate views as well as layout elements using the micro-frontend approach. Of course, as with all matters related to this subject, it all depends on the business needs. First rule of thumb, it will probably never make sense to split a simple company website using micro-frontends, it’s probably also an overkill to split simple apps — if it’s a couple of forms and tables that all tell a story inside of one business domain and the app is developed by one scrum team, it’s not worth the overhead. There’s no golden rule and every case should be analysed separately whether the cons don’t outweigh the pros.
Why should I bother?
What are the cons, you might ask? Well, microfrontends, same as microservices, don’t come without a cost, and just to list the most notable downsides:
- in most cases you’ll need to develop a way allowing the different parts of your app to communicate with each other, which adds a bit of an overhead,
- it also means that you’ll need to add some constraints to your applications that will ensure compatibility between the microfrontends that make up for portions of you application,
- it definitely adds a bit more effort to deployments and integration set up — every microfrontend needs to be deployed and administrated separately.
What do you get in return? As stated before, mileage may vary — but you can assume the following:
- however you choose to split your app, it always enables you to divide responsibility for your codebase: you can build small teams working on complete domain-specific applications (consisting of a single-domain microfrontend and a microservice) or you can make sure that each meaningful part of your app’s UI has a team that’s responsible for all of it’s features. Or anything in between!
- as long as you don’t break integration between the wrapped microfronted and the wrapper app, you can do independent deploys.
- you can mix and match different technologies in your application — you can have some parts that are written in newest Vue or React, some Angular 1.2 and a part that is a 15 year old legacy code — all of that while providing a smooth, consistent experience for the users!
- this also enables you to experiment with new stuff easier —same as with microservices, you can become totally independent of one technology; the jokes about new JS frameworks appearing daily is a bit (OK, a lot) of a exasperation, but frontend architectural decisions have a much shorter “best before” date — with the microfrontends approach you are free to develop the new feature of your app with a completely different set of tools, if you feel that they are a better fit for the job than your previous stack (but please, don’t change your stack every fifteen minutes!).
- if it makes sense business-wise, it’s pretty simple to make an application work both as a standalone and as a part of an another app!
- it promotes reusability and composition — in this approach it’s much easier and more natural to extract common code, as it’s usually the code that’s connected to the common domain that’s being repeated.
Where to begin?
How to start with implementing micro-frontends in your project? Actually, there’s a surprisingly large number of ways to do it! It can also be done at several layers of a web application — at the server side, at the client side or at the edge.
Let’s start with the edge-side includes, or ESI. It’s basically achieved by using a specific type of XML-based language, that allows the edge solution (which is nothing else than a CDN) to compose a view using responses from different URLs:
<esi:include src="https://yourwebsite.com/1.html" alt="https://backup.yourwebsite.com/2.html" onerror="continue"/>
As you can see in the example above, the implementation itself is pretty simple and it should be easy to integrate different technology stacks (except, maybe, solutions that utilise self-targeted POST requests to work but that’s a problem independent of the chosen solution and can be fixed by using a simple iframe). As far as the drawbacks go, there are two main ones: first of all, this approach requires an additional, specific layer to the app architecture (namely a CDN solution that can handle ESI), and also it’s not very fast.
Another part of an application that is suitable to do the integration on is the server, which can actually be done on different parts of the stack — either on the http server (via server-side includes, or SSI) or on the application server.
As far as SSI goes, usability-wise, it’s pretty close to ESI, but it doesn’t require an additional layer (Apache and nginx servers support it out of the box, just to name the few)— just a few more lines in the http server config file. After that’s sorted out, SSI commands can be used in the served HTML files, for example like so:
<!--#include ifheader="Referer" file="included.html" else="included2.html" -->
As for the pros and cons, it’s similar to ESI ones, except that there’s no need to add an additional layer — it all happens on an HTTP server that’s required for your web app to run anyway.
Server-side integration can also be done on the application server. It can be, of course, written from scratch, but if you’d like to start with something that’s ready to go, the first thing to look at is Podium. It’s based on the concept of a set of little Node.js servers — one for each wrapped application (these are called “podlets” in the Podium nomenclature) and one central server (a “layout” one) to stitch the podlets together into a seamless experience. Apart from that, Podium also provides some useful helpers for passing data between applications, reusing assets and so on. If you want to build a quick proof of concept, be sure to give it a go!
Should I bother at all?
OK, so how much sense do micro-frontends make? Well, as usual, it depends. If you’re developing a small company website — most probably it’s something that you shouldn’t bother about. If you’re working on a large application, that has a lot of separable UI elements or a lot of views that cover multiple domains (or both), it’s probably worth giving a shot. Anything in between — you’d need to figure this out taking your actual case into account. I’ve already mentioned the benefits and costs of this approach, and depending on the business context, architecture, the number of developers working on the app and many, many other factors the outcome may be positive or negative. Whatever you decide — let us know in the comments!