Checking session availability…
Hang tight while we load the latest updates.
Summarising 2 years of work in 30 minutes, Luca will introduce you to his vision of Microfrotnend architecture. Luca is Chief Architect at DAZN - the Netflix of sport. Luca will discuss from monolith to micro. What is a Microfrontend. The principles of Microfrontend and the technical implementations.
Micro Frontend Architecture
Luca Mezzalira at UXDX Europe. Video: https://youtu.be/BuRB3djraeM
Readable transcript: edited from the recording's captions for readability (fillers and false starts removed, punctuation and section headings added). Wording is the speaker's own. Timestamps are positions in the video. Names marked [?] could not be verified against the audio.
Introduction
[00:00:04] Thank you very much, Joe. First of all, thank you for choosing this session over the other; it's a pleasure having you here today. I'm very excited to be on the stage today because it's the first time I'm delivering this talk, and to be honest it's also very challenging, because I'm trying to summarize two years of work in 30 minutes. Today I want to introduce you to my vision of a micro-frontends architecture. It's not a new topic, but there are many approaches that we can have, and I would like to give you mine.
[00:00:40] As Joe said, my name is Luca. I'm chief architect at DAZN. DAZN is an OTT platform. It's available in seven countries, we already have hundreds of developers, and we have millions of customers. It's a really interesting challenge, because we have 30 devices that we have to keep on track and deliver our applications to, and we have a video delivery pipeline that is very complex. It's basically the Netflix of sport. I'm a Google Developer Expert on web technologies, and I organize a lot of meetups in London with my community. If you are in London and you're looking for a meetup, we usually organize one per month, so feel free to join us.
[00:01:22] What are we going to cover today? First of all, we will do a journey from a monolith to micro-anything. Then we will talk about what a micro-frontend is, we will define some principles around them, and we will end up with some technical implementations, or let's say different options that we can have in order to embrace this new architecture. First and foremost, as I said, this is the first time that I do this talk, but in order to arrive at these ideas and concepts I had to be very open-minded and question all the best software development practices that I studied in the past. So please be open-minded during this talk and think at scale, because this is one of the ways that you will better embrace this architecture.
From monolith to microservices
[00:02:13] I joined DAZN four years ago. We are still a startup in a certain way, despite the number of people that are working on DAZN. I remember the first day that I was there, the CTO [?] came to my desk and said, "Listen, Luca, I know that you are the second tech person that was hired inside this company, but at the same time I would like you to think broadly and start to think at scale, because what we would like to have in DAZN is hundreds of developers working on the same platform and the same codebase." To be honest, as an architect I was a bit scared. If you think about it, you are the second tech person that joined the company, and suddenly you discover that you already have this huge challenge: to think about an architecture that could empower developers, distributed teams across the world, working on the same codebase. It is a big challenge. So bear that in mind, and let's start this journey, which was basically the journey that I took in order to move towards the micro world, as I call it.
[00:03:20] Usually when you start a new project, or if you work in a startup, what you really care about at the beginning is retrieving feedback quickly from your potential customers. The tech stack is important but not essential. Time to market is more important, therefore you tend to maybe cut some corners. But 90% of the time what you end up having is a database that is shared across multiple APIs, you have an API layer that stores what we call a monolith, which basically contains all your APIs, integrations with third-party companies and so on, and then on the client side you have a single page application.
[00:04:05] I picked that architecture because obviously there are several others that you can pick. It could be server-side rendered, you can have single pages, but single page application is one of the most used, where you download the entire codebase and then you just consume your APIs in order to render the view. Then when you validate your ideas and the company starts to grow, you identify the areas that have to grow with the company and the organization. What you start to do is take your monolith and break it up into multiple microservices. You start to have one database per microservice, because otherwise it's an anti-pattern, using a shared database for multiple microservices. You have your infrastructure that is dedicated for that, and then you start to divide your teams following the way the business works.
[00:04:57] But what do you do on the client side? On the client usually what you have is tens of developers working on the same codebase that they started with, and it's becoming more difficult every iteration, because if they're not very prescriptive in the way that they are working, you end up with a codebase that is exploding. And it's way more difficult if you start to have distributed teams, because with distributed teams it's very, very hard, apart from pull requests, to check the outcome of your codebase and the impact on your team.
[00:05:28] So usually on the frontend side, as we said, we have a unique codebase that is managed by multiple teams, and what we need to manage a lot is the communication overhead between different parts of the organization, particularly if you have a distributed team. Instead, if you check what is happening on the infrastructure side and the backend side, they start to have a structure that allows them to scale some parts independently. They have some strong boundaries around what they are delivering, and everything became easier in a certain way, because if they design their microservices and APIs properly, they just define a contract and they stick with it. Then they are completely autonomous to deliver a new microservice or a new version. There are a lot of engineering practices that you can use to ensure that your microservice is not breaking the entire platform, also in production. But on the client side it wasn't exactly the same.
Applying microservice principles to the frontend
[00:06:28] As we said, this is our situation, and I would like you to keep it in mind, because this is how these kinds of things often work. But what if we change this? What if we start to take the principles of microservices and apply them to the client side? What if we start to say, okay, domain-driven design is not only for the backend, it could be applied on the frontend as well? At the end of the day, if you think about it, we have a monolith, we break it apart, and we start to have multiple APIs that are managed by multiple containers, or lambdas, or whatever you prefer to deal with, and then you start to have an infrastructure that is dedicated to a certain microservice. You can do the same on the frontend: you can break apart the SPA monolith. It has some challenges, obviously, because you need to find a way to orchestrate which micro-frontend you will load, but at the end of the day you can do that, and you can end up with an architecture like this. Obviously it's a simplification, but why not?
[00:07:31] If we start to dig a little bit further into that, we can start to see something very interesting. First of all, the impact on the team. As architects we often don't think too much about the process of how we structure the team, but we have to, because if we want to scale the company that is probably one of the most important things, in particular for the frontend. If you scale the frontend, you don't have to scale infrastructure, because we are delivering static files the vast majority of the time, so CDNs are doing that for us. What we need to scale and think about are the teams, because that is the complicated part.
[00:08:09] With micro-frontends we can start to introduce a way to speed up the throughput of our teams, because we can have cross-functional teams that are managing the microservice API layer, the infrastructure layer and the frontend layer in autonomy. They don't have to communicate with other teams as long as the contracts are respected. They start to have freedom and responsibility because they own the full stack, and for the first time they can innovate. As we know, one of the pleasures of working with microservices is the fact that you can have multiple technology stacks when you are designing your APIs. We can do the same with micro-frontends. You can have part of your application written in Vue.js, part with React and Redux, and part with Angular. It's totally feasible.
What a micro-frontend is
[00:08:55] So let's talk about what a micro-frontend is. This is my definition; obviously you cannot find much on the web, so I'm working hard in order to provide some information. Starting from a DDD perspective: micro-frontends are a technical representation of a business subdomain. They provide strong boundaries with clear contracts, and they avoid sharing logic with other subdomains. For me that is a definition that provides clarity on what we are trying to achieve with micro-frontends, and I would like to check the key parts of this sentence: representation of a business subdomain, with strong boundaries and clear contracts, and avoid sharing logic.
[00:09:41] Domain and subdomain is not a new concept. It's something that has been applied in domain-driven design for a while, and often domain-driven design is thought of mainly for backend layers, but we should use it on the frontend as well. So what is a domain? A domain is the problem to be addressed with the software effort. If you think about Netflix, and I hope that everyone knows what Netflix is, the domain for them is an OTT platform that is trying to deliver movies with streaming. But obviously if we take this domain all together, it's very complex, because there are a lot of things inside it that we have to think about: subscription, catalog and so on.
[00:10:23] Therefore, DDD tends to say that if you have a domain, you can split it up into multiple subdomains. Usually if you do that very well and you master the domain, you can start to map your subdomains to teams, and that is very important, because you can start to have a payment team with the infrastructure and the frontend and the backend as a cross-functional team working together with product. That is something very, very important, because when you have that, the communication overhead starts to diminish a lot.
[00:11:01] Another key concept of micro-frontends for me is share nothing. I know that it's very painful at the beginning, because the first thing that we tend to do on the frontend is, "Okay, I have to create my application. There are some components that are available in multiple areas of my application. Let's create a component library." Trust me, I've spent a lot of time working on this topic with developers, and I know the pros and cons of this. I know that there is a lot of resistance at the beginning. But if you think about microservices, usually with microservices you share really little, usually logs and monitoring, and often those are not even inside your code. What if we can do the same on the frontend?
[00:11:46] Honestly, here's what we have done. One of the things that we usually have in DAZN is a lot of people saying, "Okay, we have multiple micro-frontends, and we have the header and footer that are replicated five or six times, copied and pasted and then changed." A lot of people say, "Oh yes, but that is a bad practice, because we are copying code, and every time we need to change it we need to change it five times." But the question is, how often does the header and footer change during the lifecycle of a platform? I checked that, and we changed it twice in three years. So is it really a problem that we are adding a new label inside the header, or changing the color of the font? I don't think so. I think that the throughput is way more important than thinking, "Okay, we have to deal with this duplication of code." And if it's well addressed, it's not a big deal.
Approaches: Spotify, OpenTable and Zalando
[00:12:39] So how can we approach micro-frontends? There are several ways to do it. As I said, it's not a new concept, but we are trying to find the right way to do it. For instance, Spotify, in the desktop application, work with iframes. It's a massive application that is based on web technologies for the UI and C++ behind the scenes. What they are doing basically is creating multiple iframes that are their micro-frontends. Inside the view there is the micro-frontend for the music player, there's one for what your friends are listening to, there is the list catalog micro-frontend, and they communicate together via an event bus [?] that is injected inside each micro-frontend. That is one option. The question here is how we can assemble these views in a proper way. Probably there is another team that is doing that, probably it's the responsibility of a specific team, but still there is a lot of communication going on.
[00:13:35] OpenTable, another large organization, have distributed teams in Australia, London and San Francisco. They started this journey of micro-frontends in 2014, if I remember well, and they basically created a developer experience team that delivered OpenComponents as an open source project. Basically, when you define a component, it has frontend, backend and style, and everything is server-side rendered. The component is stored inside a registry; think about Docker, if you're familiar with that. Each single team can pick up from this registry the components that they want, and they compose the application without much communication at the end. If there is a team in Australia that is creating a header, then it could be used anywhere else. Obviously there is some coordination that has to happen cross-region, but at the end it's a really interesting approach. That is another approach to micro-frontends. For making the experience smoother for developers, they also created a CLI. But that means at the same time that a new joiner at OpenTable has to learn all these things and start to use all the tools that are available inside the company.
[00:14:54] The third example, which is the one that is closest to my ideas, is Zalando, the fashion e-commerce. Several years ago I attended a talk by one of their engineers. The interesting bit there is that they created an open source framework, Mosaic, and there is a specific part called Tailor.js. What Tailor does is basically create your pages at runtime. There is a tiny layer where every time you request a page, HTML fragments are assembled on the go. Obviously they are highly cacheable, because when you have, I don't know, a tracksuit from Adidas, it will always be the same; you don't have to serve something specific. In that case they can work at scale. They produce these pages, they cache them on a CDN, and that's it. Tailor is written in Go; it was one of the first experiments with Go for frontend, which is pretty brilliant. They were inspired by BigPipe from Facebook, so you can see BigPipe on Facebook pages; it's more or less similar. So in this case we are talking about components that are assembled at runtime on the server.
The DAZN approach: subdomains as single page applications
[00:16:13] We took a different approach in this case, because one thing that I was thinking when I was designing this architecture was, okay, now we have one small team of developers starting to work on one platform, which is web, but we need to target 30 platforms. We also need to have distributed teams that are sharing the same codebase, because they have to work on the same codebase. And who knows what could happen next?
[00:16:39] The first thing that I did was take our application, which, if you think about Netflix, is very similar, and I worked with the domains. I started to slice and dice my application into multiple subdomains. We have the landing page subdomain. We have the authentication, which contains sign in, sign up, retrieve email, reset password and payment all together. We have discover and playback, which is basically the core of DAZN, where we have the catalog, a search functionality, a schedule functionality and the playback. Then we have customer support, where we have the help and the chat, the contact us and so on. And we have my account, where you can basically change a few things. Those are the key subdomains that we have inside the DAZN domain, and those are mapped one to one with our product teams. We have a product team that is managing payment, we have a product team managing the acquisition, we have a product team managing the landing page. Sometimes the product team is composed of one person only; sometimes it's composed of more people. Discover and playback is pretty huge, for instance. But this is how we restructured things.
[00:17:50] Each of these areas is represented, technically speaking, as a single page application. Some of them are not even sharing the same technology stack. Some of them are based on React and MobX [?], some others just React, and we are doing some tests with other technologies. But all of them are completely different projects managed by different teams, and the know-how is to orchestrate them, because the complexity of this is not creating multiple single page applications, it's how we deliver them to the client. I spent a lot of time thinking about that. In order to avoid scalability issues, because the problem that we have compared to Zalando is that we need to create something highly scalable that is completely customized for the user, we cannot use the CDN too much right now for serving our content, because there are too many permutations.
The bootstrap
[00:18:44] So I created this layer, called the bootstrap, and it is the first thing that is downloaded when you type www.dazn.com [?]. It's checking where the user is watching DAZN from and retrieving the configuration for that specific country. Then it's abstracting the input-output operations for all the other single page applications, or micro-frontends. One of the problems you have when you work on TVs in particular is that the APIs for writing something on the devices are completely different between manufacturers, or within the same manufacturer between different smart TV editions. If you have Samsung Orsay [?] and Samsung Tizen, there are completely different APIs to write to. Therefore, if each single micro-frontend had to know these permutations, it means that we would need to create one for each single platform. But honestly, we can abstract that, and the bootstrap is doing this.
[00:19:49] The other thing it does is the routing between micro-frontends. It understands which state the user is in, and then based on that it retrieves the right micro-frontend. It understands if the user is signed in, and if they're signed in it will go straight to discover and playback. If they're not signed in, it will serve the landing page, unless there is a deep link, in which case it goes to the authentication page, for instance.
[00:20:21] The last thing is sharing configuration across multiple micro-frontends. Because it's a vanilla JS layer that is just exposing some stuff, we are exposing things that are happening in one micro-frontend and making them available for other micro-frontends to listen to. Also, for instance, marketing pixels or analytics like Google Tag Manager live inside the bootstrap. The bootstrap is the key to our strategy, because if you think about it, we need to deliver around 20 smart TV applications, and if I start to have device-specific code inside each single micro-frontend, it's impossible for us, because we would need so much effort in order to make it right. That is very difficult. If I abstract that in the bootstrap, it's very interesting, because it becomes very natural. I can reuse authentication everywhere without changing anything.
[00:21:20] The other interesting thing about this is what we can do on the delivery side. We can do something that is unique, because we can, for instance, maintain the current application and deliver just a subset of the functionality with this new architecture without impacting the user. Potentially we can say 30% of our users are receiving the discover and playback micro-frontend instead of the previous application, which is a single page application, but at the same time I can reuse all the rest, maintaining the authentication, landing page and stuff like that. This architecture allows us to deploy wherever we want, when we want, in a specific country, and to roll out the new version of a micro-frontend gradually, like we can do with microservices. If you think about blue-green deployment or canary releases, we can do exactly the same thing with this architecture.
What we gained
[00:22:21] If we think about what we have gained with micro-frontends: first and foremost, a micro-frontend is not a component. It is a representation of a subdomain that matches exactly the structure of our organization. It's technology and framework agnostic, as I said: I can develop one micro-frontend in one technology and use another one for another micro-frontend. Each micro-frontend exposes lifecycle methods that are used by the bootstrap when we want to unload or mount the micro-frontend and do some things inside it. Each team inside the micro-frontend can share components, code, style and any other stuff like that, but they cannot do that outside the micro-frontend, because that is going to slow down everything.
[00:23:02] I've worked in a lot of large organizations managing hundreds of developers, and when you start to abstract and have a team that is centralizing code, that is where the throughput goes nuts. You start to have a centralized version of your code, and every time you need to change it you need to add another abstraction, the code becomes more difficult to maintain, and in six months' time the throughput is gone. Structured this way, we can isolate the team, they can take their own decisions, and they can innovate inside that. The other interesting thing is that we can test different build systems. One micro-frontend could be built with webpack, another one with Parcel, and so on. So we can really have a granularity of choice with this, which is brilliant.
[00:23:52] What did we achieve? First of all, and this is for me pretty interesting, we were able to onboard five teams in a couple of weeks' time. After the first week they were able to contribute to the codebase immediately, because they are completely independent. They don't have to wait to deeply understand the architecture. They have their own single page application that is really tiny and small, and the domain is small, so they can understand the domain deeply and then start to work on it. We currently have over a hundred developers working on the same codebase, which is brilliant, and also in a distributed way, because we have people in Poland, we have people in London, and we are opening a new dev center in Amsterdam [?] right now. That is one of the powers of this.
[00:24:35] Finally, the developers have the freedom and possibility to innovate, owning the code end to end and not just part of it. Too often architects think just about the API layer, but it's not the API layer that is the complex one, because currently we have a lot of ways, patterns and architectures that could help us scale it up. But for frontend, we don't have much.
Frameworks and wrap-up
[00:25:02] If you want to start to look deeply at micro-frontends, I picked these two projects. There aren't many. As I showed before, you can have OpenComponents, and there are other ways to do it, like Tailor.js, but the two that for me are closest to my mindset are these two frameworks. One is single-spa, which is not well known but provides a structure that is very similar to what we built. Unfortunately I discovered it too late in the process, a year after we started to work on this, but it is a really interesting one. And then FrintJS [?] provides slightly more flexibility and freedom compared to single-spa. It's another interesting one. It leverages reactive programming behind the scenes, and you can create components with different frameworks, and Frint will collect them and show them inside the same [?] view. So this is an interesting one as well.
[00:26:01] To wrap up, I would like to summarize what we have seen till now. When we scale frontend applications, the problem is not scaling infrastructure, it's scaling the teams. We have to take this into consideration, because it's very, very important to have the right throughput and to reduce the communication overhead between teams. Last but not least, developers often move from one company to another. I don't know how the industry is here, but in London they change more or less every year, year and a half, mainly because they want to try something new. With micro-frontends you are basically providing them what they are looking for inside the organization, so it could also be a good way to retain people.
[00:26:45] Last but not least, if you're interested to know more about micro-frontends, because in 30 minutes it's very difficult to summarize everything, I'm writing a report for O'Reilly right now. It will be a free report, probably available by the end of the year. I'm doing a learning session, on the 18th of October, online, that is fully free; you can check out my social profiles. And hopefully from next year I will be able to dedicate some of my time to writing a full book on micro-frontends. That's it for me. I know that we have some time for questions, but if we are not able to speak right now, I'm around for these two days, so please feel free to stop me and challenge all the ideas that I shared. As I said at the beginning, it's two years' work, and having a fresh point of view could only help. Thank you very much.

