Loosely Coupled - Interoperability in Micro-frontends
Karol:
Good morning, good afternoon, and good evening, everybody, and welcome to another episode of Loosely Coupled by Bridging the Gap.
Karol:
My name is Karol Skrzymowski, and I'll be your host tonight.
Karol:
Hopefully, all of you have a lovely cup of something to drink for this session.
Karol:
I don't know if you noticed, if you're coming back to the stream, maybe you have, but we actually have a jingle today.
Karol:
That's made by my co-researcher at Bridging the Gap, Filip Kostyra.
Karol:
Thank you, Filip, for that.
Karol:
It's a work in progress, but it's already pretty nice.
Karol:
Filip doesn't want to say that this is a ready thing.
Karol:
He said he'll work on it in January, so maybe there will be a different version, maybe a longer one.
Karol:
But that's not the topic for today.
Karol:
This is actually the last stream this year, and here today, we have a lovely topic of interoperability, so actually something we do at Bridging the Gap, and today, a different angle.
Karol:
We're going to be talking about interoperability in front-ends, and specifically micro front-ends.
Karol:
Who better to talk about interoperability in micro front-ends than the author of the book Building Micro Front-ends, Luca Mezzalira.
Karol:
Luca, welcome to the show.
Luca:
Hi, everyone.
Luca:
Thank you for the invite, Karol.
Karol:
Happy to have you.
Karol:
Luca, you've been at it for the last, what, 21 years?
Luca:
Yeah.
Karol:
Doing IT stuff, architecture, and whatnot?
Luca:
Yes, more or less, I think 24 in January.
Karol:
24?
Karol:
Whoa, okay.
Karol:
24 in January.
Karol:
Wow.
Karol:
You wrote me in the bio since 2004, so I'm like, 21 years since I've been here.
Luca:
No, I did also something before that.
Luca:
Ah, so that's in architecture.
Luca:
If we want to start on the very beginning, yes.
Luca:
2004 was the first line of code, if you want, but I did also some stuff before that.
Karol:
Fair enough, fair enough.
Karol:
Luca, micro front-ends, how old is this topic?
Karol:
Because you've been at it for a while already.
Luca:
Yeah, I'm ranting about micro front-ends for almost 10 years.
Luca:
So next year, if I remember well, is in May.
Luca:
That will be the first decade of the term micro front-ends that was coined by ThoughtWorks.
Luca:
One of the developers in ThoughtWorks came up with this idea, Mr. Jackson, if I remember correctly.
Luca:
And then it was advertised inside the tech radar that they usually do twice per year.
Luca:
It was the first half of the year, if I remember correctly.
Luca:
Therefore, I started before this term was coined in 2015, thinking about micro front-ends and how I can apply the principle behind microservices in a way that makes sense for front-ends.
Luca:
And then suddenly in 2016, we started the development.
Luca:
It took me a good amount of time having the buy-in inside the company.
Luca:
Because as you can imagine, if you go to a CTO and you say, OK, we are going to do this in this architecture.
Luca:
And the question, how many companies are doing that?
Luca:
And the answer was probably one or two in the world.
Luca:
It wasn't, let's say, the most sustainable things that you can say to a CTO.
Luca:
So we need to prove that.
Luca:
So I had a team of a few engineers that work with me in order to create a POC that would show how we solve the challenges we were facing in our monolith.
Luca:
And that basically was the beginning of the story of micro front-ends.
Karol:
I mean, 2015 in Poland at that time, I think people barely heard about virtualisation.
Karol:
They started hearing.
Karol:
I remember going to a session with Microsoft somewhere in Warsaw.
Karol:
They were showing off their Hyper-V servers.
Karol:
That was the pinnacle of virtualisation back then.
Karol:
In T-Mobile, we were still running some servers on bare metal.
Karol:
But these were just huge monolithic servers in that sense.
Karol:
So we had like separate servers to have higher availability.
Karol:
So that's quite a long run already.
Luca:
Yes.
Karol:
Ten years.
Karol:
Yeah, you started early, basically.
Luca:
I started for a necessity.
Luca:
The problem that I had to solve back in the days was being part of a startup that turned out to be a unicorn based in London.
Luca:
And we moved from 50 people to 3,500 in something like a couple of years.
Luca:
Because the challenge was we worked with a lot of partners.
Luca:
The first iteration was working with partners.
Luca:
I was working for one of the partners.
Luca:
And I followed basically the integration with different tools that we were using.
Luca:
Because we were the company responsible for the front-end as well as the middleware that was aggregating all the data and generating also other data.
Luca:
And then after that, after the first release, I've been asked if I would be interested to join this company that I was working for.
Luca:
And the answer for me was like, yes, without any doubt.
Luca:
Because the idea was scaling the way how we were doing the first release of the software.
Luca:
But most importantly, revolutionised the way how people were consuming the sport.
Luca:
And at the time, Netflix was starting to boom properly.
Luca:
And if you think about that, it was like a perfect storm where you have like sport that you don't have to explain to anyone what sport means.
Luca:
And you have like streaming, on-demand streaming that was starting to grow.
Luca:
And I found myself in a situation where I was the second tech person hired in that company.
Luca:
And they told me, okay, now we need to internalise all the things that we have done with partners.
Luca:
So we need to create all the hiring process, all the architecture, all the team structure, all the engineering practises and so on.
Luca:
And I was basically the second person that had a lot of say on all these topics and looking holistically on the social technical system that we were building.
Luca:
And we started to introduce things way before certain things came out.
Luca:
Like the idea of team topologies, for instance, was something that the book came out in 2019.
Luca:
We were doing that in 2017 internally.
Luca:
We didn't have a name.
Luca:
We were just, let's say, leveraging domain-driven design for splitting up, let's say, our application, find the boundaries and subdomains.
Luca:
And then co-locating, because it was pre-pandemic, co-locating the people working on the same subdomain in the same hub.
Luca:
Because we have four different hubs.
Luca:
There's one in Poland, in Katowice, one in Amsterdam, one in Leeds, and one in London.
Luca:
And basically aggregated these subdomains in a way that the worst-case scenario, you solve the problem with a person that is like 10 feet from your desk and not on a one-hour difference or in another city or even in another country.
Luca:
So therefore, that idea accelerated basically the storming and forming of the teams.
Luca:
And also, we know upfront that in order to solve the problem of, let's say, communication across different hubs, it was just working properly with the API contract first and having, let's say, strong governance around, I need to change an API, perfect, write an RFC and start working to that.
Luca:
So we started to create a lot of practises that I recognise nowadays that I'm in AWS, that many companies currently are still at the beginning of the journey that they did, let's say, almost 10 years ago.
Luca:
So it's very interesting because it seems that we were extremely futuristic to a certain extent.
Luca:
I'm pretty sure other companies have done what we have done at the time.
Luca:
But for many enterprises I'm dealing with right now, a lot of learnings that I have went through over the past decade are definitely helpful for them to, let's say, embrace this new world of modernised software, modernised architecture.
Karol:
Now, okay, that's a handful.
Karol:
I'm like sitting there, it's like the light bulbs switching on in my head.
Karol:
Okay, Conway's Law, team topologies, cognitive load, so many of those topics.
Karol:
There's so much to unpack here.
Karol:
So basically you were at the forefront of developing new approaches in tech and then actually have practical experience when they already were named and went out with specific names.
Karol:
So you already have experience in dealing with that in practise.
Luca:
Yeah.
Karol:
That's a rare thing.
Luca:
It was because it was, you know, the cool thing for me was I was, let's say, a person that loves to work in bleeding edge context, where things you don't know if they are going to work or not.
Luca:
Because we need to bear in mind that in 2015, when we launched the first release of the zone, there wasn't this idea of live sports streaming.
Luca:
Many people were telling us there is no way you can succeed.
Luca:
No one did that before.
Luca:
There is the cable providers.
Luca:
That is the normal way how to consume sport back in the days from Sky and many others where the way how people were consuming, they were working perfectly fine.
Luca:
We believe that we can democratise even further sport and reduce the cost.
Luca:
And in fact, the first few years, the cost of our subscription was less than 10 euros per month.
Luca:
And you can consume everything that was available in your country.
Luca:
Obviously, we started with four countries.
Luca:
The first release was Japan and DAC, that basically is Germany, Austria and Switzerland.
Luca:
And in Japan, for instance, we acquired for 10 years exclusive rights for the J-League, that is the football or soccer for our friends in America.
Luca:
That leagues for what we put like the first one, second one and the third one.
Luca:
And after that, in 18 months, we became almost the only sport broadcaster.
Luca:
The only thing we didn't have was sumo.
Luca:
But we had everything else.
Luca:
We brought, let's say, all the other sports from U.S., a lot of sports from Europe, the Champions League and all the other things.
Luca:
So it became extremely popular in Japan.
Luca:
And I remember when I was working there, because obviously I was used, let's say, more or less in every single launch, staying in the war rooms and seeing how the things were panning out from our first Datadog and the New Relic dashboards.
Luca:
Quite fun.
Luca:
But I've seen, let's say, the power of these things.
Luca:
If you were, let's say, walking through Shibuya, that was one of the key areas of Tokyo.
Luca:
In the Shibuya station, the station was completely packed with our advertising.
Luca:
You can see, let's say, our brand everywhere.
Luca:
When we launched in Italy, in Milan, we have near the San Siro stadium, that is the AC Milan stadium.
Luca:
That was like, the stadium was called the Zone Stop.
Luca:
So it was like, we started to grow like crazy.
Luca:
And obviously the way how we were designing things and implementing things at the piece that we were doing everything was quite monumental.
Luca:
At the end of the day, after a couple of years, we reached like 550 techies across the tech department spreading for dev centres.
Karol:
That's a lot.
Karol:
That's a lot of stuff in a very short period of time then.
Karol:
So not only were you at the forefront of developing new approaches, you also had the organisational challenges of extremely fast growing company.
Karol:
Which I can imagine that was for some people, not all of them, but for some people that must have been extremely stressful to get through that.
Karol:
The growing pains of a company growing that fast, this can be really great or can be really, really tragic for certain companies if they don't adapt and adopt in a very fast manner.
Luca:
I think our strength was, let's say, trying different things, analyse what we were doing and see where we were failing and adapt as soon as fast as possible.
Luca:
And I found myself having, let's say, every other week a brand new team of beginning contractors then replaced with internals to onboard these teams every other week, explaining the architecture, explaining what we were trying to do and all the other things.
Luca:
And that's why back in the days, because we had to support, the idea was supporting roughly 40 different targets on the front end.
Luca:
So set-top boxes and living room devices or console, web, mobile.
Luca:
So if you start to put everything together across the world, you have devices that were as powerful as a Nokia phone back in the days that were set-top boxes.
Luca:
But the penetration of a set-top box or a smart TV is by far larger than the newest one.
Luca:
Because if you think about how often we change the TV or set-top box, it's not happening very often.
Luca:
So there were devices that were quite obsolete technologically speaking, but in order to make them cheap, they didn't have an amazing chipset or crazy codec or whatever.
Luca:
You need to adapt yourself in the way that the things that you want to, you need to develop.
Luca:
Therefore, also one of the ideas behind Micron Tenths was, that was also one of the key aspects, is trying to reduce and optimise the memory management in JavaScript.
Luca:
Not loading everything in one go like you could do with a single page application.
Luca:
And therefore, lazy loading, what is needed, when was needed.
Luca:
And I think we did a pretty good job overall on doing that.
Luca:
And that basically not only enabled the performance, but enables us to have teams that were working independently.
Luca:
Because now with the good segregation of concern and division about domains, we were capable to say, okay, so this team is responsible for this part and that team is responsible for that part.
Luca:
We had to iterate for more or less a year and a half to figure out the right split.
Luca:
And understanding and fixing all the different problems.
Luca:
Because obviously, as you can imagine, because it was so novel, this approach, there wasn't documentation.
Luca:
There weren't, let's say, any book that could tell you, oh, this is the way you should do.
Luca:
Or someone that you can say, oh, let's call a consultant to help us to do this.
Luca:
Completely.
Luca:
So all the meetings that they organised with 10, 15 developers for trying to analyse the problem, trying to see the patterns we can apply, trying to see what fit, what didn't.
Luca:
After, let's say, a couple of years when we started to launch on the web first, I thought that we were sitting in something extremely interesting.
Luca:
Because it was a journey of two years gathering feedback from different developers, from junior to senior and principal, etc.
Luca:
And then I remember the first talk very vividly that I did in Dublin, where I went on purpose and the conference was not too big, but was big enough with hundreds of people.
Luca:
They gave me like 35 minutes for delivering the talk.
Luca:
And I spent roughly four hours answering questions after.
Luca:
It was like I couldn't have lunch because people literally assault me on asking, OK, how do you manage the design system?
Luca:
How do you do this?
Luca:
How do you do that?
Luca:
And it was extremely funny on one side and extremely rewarding on the other side.
Luca:
Because, you know, we work for something that probably no one has explored at that depth like we did.
Luca:
And then suddenly there is an interest that is out, but all companies that were huge compared to what we were at back in the days.
Luca:
And so for me, it was a great reward and great moment overall, despite there were other lows later on during the journey.
Luca:
But, you know, here we are.
Luca:
We have the same microphone that is used everywhere from all the enterprise, largest enterprise in the world probably are using some shape or form of microphone.
Karol:
Well, now, luckily, we have people that actually specialise in microfrontends.
Karol:
There is some reference to go with.
Karol:
So one of the reference here on screen, that's Lucas' book, Building Microfrontends, second edition.
Karol:
That's very fresh, right?
Karol:
That was this year?
Luca:
Yes.
Luca:
So it was released in early November 2025.
Luca:
And the cool thing is that basically it was a complete rewrite.
Luca:
I kept like half of the book and update every single chapter with the latest and greatest.
Luca:
But then I basically gather all the feedback from the first edition where they were asking, can you share more code?
Luca:
Can you do more of this?
Luca:
Can you do more of that?
Luca:
And then gathering the thing that shift basically the gear between the first and second edition is that I joined AWS right after I publish almost the first edition.
Luca:
I was about to publish.
Luca:
I wait a few months more for gathering more information.
Luca:
But since then, basically the last five years in AWS, I work with hundreds of teams, internal teams from Amazon, AWS, etc.
Luca:
And customers from Silicon Valley to New Zealand in different industries, finance, entertainment, retailers, etc., healthcare.
Luca:
And we started to, I started to collect all the patterns that I was seeing and mistakes that were happening in the trenches.
Luca:
But I think that was, let's say, a great effort for the community because what I was thinking is, okay, let's validate what we wrote in the first edition.
Luca:
And let's add other new approaches that were surfacing there and generating the vocabulary like I did in the first edition.
Luca:
Because the vocabulary, as you know, naming convention and ideas that you need to convey require a certain type of language.
Luca:
So for me, you know, now I'm working certain engagement with customers where they are talking the language that I created back in the days.
Luca:
That is insane on one side, but it's extremely helpful because everyone is on the same page.
Luca:
And that doesn't matter if they are in the UK, in the US or in New Zealand.
Luca:
We will talk exactly the same thing.
Luca:
So we are on the same page.
Luca:
We start to discuss what kind of challenges they have.
Luca:
It's a completely different way.
Luca:
And I have to say, one day I will document properly how to create a vocabulary for an architecture.
Luca:
Because I realised that there is a lot of thought process behind that and why certain things were described and designed in a certain way.
Luca:
And, you know, after 10 years, I have a lot of data points that I can say, okay, I can identify what are anti-patterns and what are patterns that you should embrace.
Luca:
And how the influence of other architectures helped me to reach the maturity level that we have currently.
Karol:
You said a word that triggers me into asking.
Karol:
Because I did plenty of research in terms of patterns and anti-patterns.
Karol:
When I was designing a course on integration architecture some time ago, I struggled with finding a decent definition of an anti-pattern.
Karol:
What's your definition of an anti-pattern?
Luca:
So it's the opposite of a pattern.
Luca:
What I would define is an approach that when taken, it will generate more friction than benefit for a company.
Luca:
It doesn't mean that it will always generate that friction, but it's likely to generate friction.
Luca:
There is this concept that I truly believe in where a pattern is a solution for a common problem.
Luca:
But not always you want to embrace best practises or patterns or you want to embrace anti-patterns sometimes.
Luca:
Because the reality is, and that is me becoming more mature and having more experience and more years under my belt.
Luca:
The fact that in the past as a developer, you are dogmatic.
Luca:
You say, okay, this is MVC.
Luca:
You implement MVC by the book.
Luca:
You implemented the pattern by the book.
Luca:
And if someone is trying to convince you that this is a bad way to implement a specific part, you say, oh, no, no, but you don't understand.
Luca:
Because in reality, this is a part that is documented here, the Gang of Four, so see it.
Luca:
And now instead, I'm more into the trade-off analysis like Neil Ford and Mark Richard recommends.
Luca:
Okay, so let's try first to analyse what we need to express inside the system or inside the future.
Luca:
And then after that, when I have like the business capabilities crystal and clear in my head, I have the architecture characteristics.
Luca:
I hate non-functional requirements, so don't ask me to say that.
Karol:
I subscribe to that.
Luca:
Architecture characteristics that I need to express inside the system because some of them I need to apply across the entire system.
Luca:
Some of them I need to apply maybe in a specific domain, generic or core or supporting.
Luca:
And therefore, if you start to work in this way, you start to have, let's say, clarity of what you can and what you cannot do at least.
Luca:
And then you can challenge, obviously, this specific implementation because maybe it's a snowflake or maybe you discover that it's not.
Luca:
But unless you start to have, let's say, a conversation that you first understand these two layers, basically as business and what architecture would like to see.
Luca:
For obvious reasons, sometimes you're working in regulated environment or industry.
Luca:
Sometimes it's, let's say, something that is a decision made by the company or by the CTO for maintaining high availability.
Luca:
So these kind of things matters and affect your design.
Luca:
And therefore, for me, when I have those, I can start to drill down into, okay, now that we know this and we know the specs, we know what we need to aim, we should for, okay, how we design this thing.
Luca:
This is one thing that I believe now we are losing because we are rushing towards the implementation phase due to time commitments that are not, let's say, managed by us.
Luca:
But I believe that the architects that are still useful should enable teams to, let's say, reframe these things in a way that they will enable to quickly have this information, key business characteristics, key architecture characteristics in a digestible way.
Luca:
And they can, let's say, incorporate in their design when time comes.
Karol:
So for those not having the frame of reference for all the terms that Luca just used, which are the terms we've been using on this live stream for quite a while already, because I do subscribe to all the terms described by Mark Richards and Neil Ford.
Karol:
I absolutely love their rhetoric around building architecture and doing trade-off analysis.
Karol:
But while you were describing this, I took the liberty of grabbing some links from O'Reilly.
Karol:
So if you need a reference to all those lovely terms that Luca just mentioned, Head First Software Architecture is a great book to start with.
Karol:
Very light read with exercises, with lots of fun for the brain.
Karol:
And if you need more of a concrete read than Fundamentals of Software Architecture, the second edition was also published this year, earlier in the year, as far as I remember.
Karol:
O'Reilly says March 2025.
Karol:
So these are really great books to find all the definitions of the terms around architectural characteristics, doing trade-off analysis, looking at all the different factors that come into the design of your architecture so that it actually is fit for purpose rather than art.
Luca:
Exactly.
Karol:
So that's the biggest value.
Karol:
Being dogmatic, I was dogmatic as well.
Karol:
I used to have that approach a few years back.
Karol:
Learned the hard way that being dogmatic is not exactly the best approach because at a certain point with one of my clients, I actually looked at it and it's like, oh, this will completely not fit the case.
Karol:
And I've been proposing that.
Karol:
It's like, no, that's just going to be a huge failure.
Karol:
Luckily, realised on the design phase, not in implementation.
Karol:
But basically, after that, I started looking more into trade-off analysis and actually analysing the context and spending more time in the problem space, analysing what the main problem is, and then diving into details of design and picking the right tools for the job.
Karol:
And while your short answer for the anti-pattern, I was instantly like, oh, no.
Karol:
And then you elaborated on that.
Karol:
And I was like, oh, yes, exactly.
Karol:
I'm joking with Mark a bit.
Karol:
Mark actually introduced a third term to the mix.
Karol:
Pattern, anti-pattern, and a pitfall.
Karol:
So now we have pattern, which is a common solution for a common problem.
Karol:
Anti-pattern, which is something that usually leads to problems when misused.
Karol:
But it's also a pattern.
Karol:
So it also solves some problems in a very specific context, niche context, usually.
Karol:
And then pitfall is something that is definitely not wise to do.
Karol:
So that's their classification of different aspects.
Karol:
And that goes on all levels of abstraction.
Karol:
There are patterns and anti-patterns everywhere.
Karol:
I have my own specific integration patterns and anti-patterns and pitfalls.
Karol:
Always a fun discussion.
Karol:
But not today.
Karol:
So having all that amazing background, because that's been quite an interesting story.
Karol:
Maybe we should dive into those frontends.
Karol:
So starting with what are micro frontends?
Karol:
Because that's the interesting definition then, after 10 years of working with them.
Luca:
Let me more than just sharing the core definition.
Luca:
Let's say walking through my reasoning when back in the days I started to think about that.
Luca:
So the idea was very simple.
Luca:
On the backend, we knew exactly what to do.
Luca:
So we knew that we needed a distributed system.
Luca:
At the time, cell-based architecture was still fuzzy, very far, far away.
Luca:
And we were just starting.
Luca:
It didn't make any sense using a cell-based architecture.
Luca:
But a microservice one definitely made sense.
Luca:
Because we were moving from a monolith to this distributed system with a lot of engineers.
Luca:
So when I started to think about what characteristics should I apply on the frontend, the majority of the time and all the different implementations I've done in the past were in a monolithic space where literally you start with all the good intentions.
Luca:
You start to scale the teams, because usually you start with one team, start to build a small POC, then start to grow.
Luca:
And slowly but steadily you have five teams, six teams, whatever.
Luca:
When we were working on this specific project, we were roughly 40, 50 people end-to-end in my previous company.
Luca:
And we were working with a monolith in the front and a monolith on the back.
Luca:
At some point, the problem we were facing is, A, and that's something I've seen in other companies when I was working as tech lead, A, we started to slow down with new features implementation, because now the code is larger and more complicated.
Luca:
People were stretched a lot.
Luca:
When you were on call, you needed to take care about, I don't know, sign-in, as well as payment, as well as catalogue, as well as any other part of the application.
Luca:
And you cannot squeeze everything inside your head.
Luca:
So the cognitive load that we were discussing at the beginning.
Luca:
The other challenge is that because there were some features that were easy to implement, we couldn't deploy them quickly because we need to retest due to, let's say, issues that happen or bugs that were happening when we started to build stuff and deploy stuff.
Luca:
We were more careful on what we wanted to deploy.
Luca:
So there were more tests, either automation or with manual QAs.
Luca:
And so if you start to put everything together, you see that there is an inherited complexity when you reach a certain point, not on the code side that I would say in every company I work for, there are some times that you have spaghetti code.
Luca:
But majority of the time, you have, let's say, people that really care about their craft and they want to do the best, and that's why it takes longer, but also helps to optimise certain things that could be refactoring on performance and that stuff.
Luca:
But the problem we had is now we have a completely different ballpark.
Luca:
We know up front that we are going to scale.
Luca:
We know up front that we need some teams that are going to take into account different domains.
Luca:
Therefore, it was stupid for me starting with saying, let's use the same approach, because otherwise we arrive to a bottleneck where the back end starts to have microservices.
Luca:
The front end has a monolith.
Luca:
They start to have bazillion of feature flags spread across the code base, and we are not going to have time for fixing that.
Luca:
So we need to think about a different approach and looking into the characteristics of microservices.
Luca:
So you know that there are defined units that have strong boundaries, not only on the code level, but also on the infrastructure level, and that is one key aspect of micro frontends.
Luca:
Therefore, we need to have an artefact, in the case of microservices, was a container back in the days, or a VM, that is strong enough that I deploy this chunk independently from the rest.
Luca:
That is not only code that they build at compile time, but it's something that they do at run time in the case of the front end.
Luca:
So I load a chunk of the system, and I lazy load a chunk of JavaScript.
Luca:
And that was the first assumption.
Luca:
The second one is, I want to have the team independence.
Luca:
Therefore, shareability, we need to be careful.
Luca:
We need to rewrite the game where in front end, when you have three lines of code that repeats twice, immediately you create a library.
Luca:
And that is evil, because when you have, let's say, a lot of external dependency, we need to reduce them.
Luca:
So we need to try to be extremely careful on what we want to, let's say, reuse, and how, and having a strong governance into that.
Luca:
And governance is not easy, because it involves people.
Luca:
And therefore, we were thinking of something that it didn't involve people, but maintain the boundaries of a team.
Luca:
And the idea is, let's start with duplication, because definitely duplicating is far cheaper than the wrong abstraction.
Luca:
So, like Sandy Metz said several times.
Luca:
And the idea is, okay, so if we start to do that, we need to be intentional what is available and shareable between teams.
Luca:
And the other thing is, we need to create an artefact that makes my team independent.
Luca:
Because the reality is the distributed system is not designed only for technology, where, yes, you have, let's say, the possibility to, let's say, deploy something, there is a bug in an area, and only that chunk is affected, the rest of the application works perfectly, but it's mainly designed for your organisation, for your people.
Luca:
Therefore, when you are designing this, you need to think about, okay, so if I have a team that is responsible for the catalogue, I think about the catalogue of Netflix, where you have, like, a lot of rails with all the different shows and different things.
Luca:
Then you select one, you have the details, and when you're happy, you click play, and the video player starts.
Luca:
Think about that, that could be a nicely encapsulated chunk of the system for an authenticated user that enables the people to, let's say, consume and can assign to the team because it's not too complex, it can be incorporated very well, and that basically, for me, was the first microphone that we built.
Luca:
But then suddenly, when we look into the video player, we saw a lot of complexity.
Luca:
We had two teams only dedicated on video players, where these teams were responsible for creating the heuristics and tweaking the heuristics on existing video players.
Luca:
For live content, it was completely different from on-demand, and every browser has its own codec, and therefore, we had to change the way how we were working.
Luca:
So now we had a microphone tag that lives inside another one, so the catalogue basically was one microphone tag that was loaded, and the other one was a video player.
Luca:
So in order to communicate, we need to think about how we are going to define this contract in an API contract first.
Luca:
So you start to see a lot of similarities on microservices.
Luca:
What I'm describing basically is the application of the practises that we are used to doing in a distributed system into front-end that before, it didn't happen, and today, people are still struggling because you need to have the experience on the other side in order to understand what fits on this side.
Luca:
So you need to understand deeply both in order to see, okay, this practise, I can use it.
Luca:
This one, it will never work because there is no constraint and no need on front-end to do certain things.
Luca:
And therefore, it's super fascinating for me that period of my life where I started to bring, let's say, patterns and mechanisms that were applying software engineering and see how I could shape them for front-end, if it makes sense.
Karol:
Unpacking that in my brain will take a moment, but basically, to put a little summary on top of this.
Karol:
So the problem space is basically the difference between we do IT now and do IT 20 years ago is the scale and the speed, right?
Karol:
So if you look at this, this is no longer a technical problem.
Karol:
It's a socio-technical problem.
Karol:
And this is not a problem of writing good code.
Karol:
It's a problem of writing good code in cohesion of responsibility and accountability for said code distributed among several teams.
Karol:
So we're basically definitely hitting Conway's Law as a problem, right?
Karol:
So we need to design in a reverse Conway manoeuvre so that we change our organisation towards the functionalities that we're building, split in domains, subdomains, and pieces of code being microservices assigned specifically.
Karol:
So the distribution of that system is a socio-technical distribution rather than purely technical.
Karol:
And of course, if we do it purely technical, yeah, we have a chunk of code.
Karol:
It's easier to change, easier to isolate.
Karol:
Only that part is, and the closest dependents are impacted by a bug.
Karol:
Fine.
Karol:
But in a software lifecycle, that's a lot more to tackle in that sense.
Karol:
Yeah, there's plenty more.
Karol:
If we were doing this on a monolith, then we would have not only the whole system impacted by a bug, we would have also plenty of other teams impacted by the same bug.
Karol:
Where if we distribute that, we have less teams impacted, but that requires more organisational work and governance between those teams.
Karol:
And this is also where coupling kicks in, in communication between modules, microservices, and communication between teams.
Karol:
We have different types of coupling between them now.
Karol:
And now the question is, what's going on in that coupling?
Karol:
Because that's interoperability on two different scales, one being technical interoperability and the other one being the human-to-human interoperability.
Karol:
Because I just finished a course from Vlad Kolonov this Monday.
Karol:
The course was on Friday, but I watched the recording because I couldn't join.
Karol:
I'll pop one interesting slide, if I can find it.
Karol:
I think this is, yeah, this is the one.
Karol:
I'll pop it on screen.
Karol:
There we go.
Karol:
So I had quite some fun looking at this table.
Karol:
Vlad describes three distinct axes of qualities of coupling, two of them being distance and knowledge.
Karol:
And the interesting part in this is that I have never really considered looking, without looking at this table, is that low distance and low knowledge is actually something of a problem.
Karol:
It's problematic.
Karol:
I think this is something that you probably did tackle in the early days of microfrontends as well, that you had low distance between the specific microfrontends, but the teams didn't understand and know what those specific microfrontends did, which created lots of extraneous cognitive load in trying to figure out what the hell is going on.
Luca:
Correct.
Karol:
And then, of course, if we look at it from my perspective of an integration architect, I'm usually in high distance, high knowledge being the problem, because that's the tight coupling between various domain systems, which is something you probably do not experience that much in microfrontends per se.
Karol:
But if you communicate microfrontends with the rest of the ecosystem, that's probably something that also may happen at times.
Luca:
Yeah.
Luca:
The challenge I face multiple times is shifting the way how people were thinking about this, let's say, interoperability between microfrontends, because there is a different dimension when you think about that.
Luca:
You can have multiple microfrontends in the same view, and that basically means that at some point they need to communicate.
Luca:
99% of the time, because since 2015, frontend was, let's say, working with the state management system, people were creating this thing called global state management that everyone can get access, write, read, whatever.
Luca:
But it's more or less like having a single database for multiple microservices.
Luca:
What happens if I change the schema?
Luca:
Everything will have a ripple apart effect, and I need to retest everything, and I need to redeploy everything together, and it's going to be a colossal problem where people then point the finger towards, oh, microservices sucks.
Luca:
That is not true.
Luca:
They are just a specific challenge.
Karol:
And that's also similar if you apply orchestration.
Karol:
That's also a single point of tighter coupling in microservices in that sense, because the orchestrator needs to know a lot more about state.
Karol:
By the way, the next slide from this deck is this, which is basically showing what these lead to.
Karol:
We have complexity and complexity, which is the things we tackle at different areas.
Karol:
You tackle that in frontend.
Karol:
I tackle that in system-to-system interoperability.
Karol:
The anecdote here that Vlad shared over his course is that when he asked this over a conference where people would like to be, would they want to be in the green or the red zone or the orange zone, actually quite a number of people pointed that they would rather be in the orange zone.
Karol:
And we're going back to sociotechnical problems.
Karol:
Job stability, job safety being the answer, why would they remain in the orange zone, which is interesting, because if they overcomplicate and make complexity, then they are secure for a job because nobody can figure out what's going on.
Karol:
And that's not the aim of neither proper integration architecture nor building microfrontends in that sense, because we want these things to be, let's say, somewhat simpler so that we actually can figure out what's going on and not have that additional cognitive load that makes us just horrendously tired over figuring out what's going on in our systems, right?
Karol:
So looking at microservices, okay, microservices being, sorry, microfrontends being a specific, very specific specialised version of microservices that expose frontends.
Karol:
They expose frontends in various ways.
Karol:
We'll probably dig into that in a minute.
Karol:
Now, if you could outline, what are the key differences of microfrontends to the traditional approach to frontends, the monolithic approach?
Luca:
You can share the screen that I'm sharing.
Luca:
I can show you and walk you through something concrete.
Luca:
Yeah, perfect.
Karol:
Let's do this, of course.
Luca:
Okay, this one is an example.
Luca:
I imagine that this is an e-commerce.
Luca:
I'm not a designer, so don't expect great things from this e-commerce.
Luca:
I'm sorry about that, but I prefer to code.
Luca:
But the idea is very simple.
Luca:
So usually microfrontends, in some shape or form, you have what is called an application shell.
Luca:
This is as simple as a container.
Luca:
So if you type www.mysite.com, first thing that you are going to have as responses is an application shell.
Luca:
That generates something that lives for the entire user session.
Luca:
So it would be there for the entire time and takes care about common things that you need to do with microfrontends.
Luca:
So routing, composing microfrontends.
Luca:
It takes care about retrieving the first, let's say, configuration that is read-only for microfrontends.
Luca:
That's another thing that's important.
Luca:
So you cannot tamper it.
Luca:
There are techniques in JavaScript, like if you use object.freeze as a method, basically makes that object readable, but not writable.
Luca:
And that's one technique that you can use.
Luca:
I used it for almost 20 years when I was working on this stuff.
Luca:
And it's a good technique for saying, OK, I have this object.
Luca:
I created and manipulated it in a certain way.
Luca:
You bound to the contract.
Luca:
You cannot change the contract, because in JavaScript, that is dynamic language.
Luca:
You can change whatever you want in the way that you want.
Luca:
And that's why you have often errors that are bubbling up here and there.
Luca:
And then in this part, usually what you want to have, it's the most stable part of the application that change context by context.
Luca:
I'll give you an example.
Luca:
This header, for instance, is as a navigation with another.
Luca:
And that doesn't change in this example.
Luca:
There are companies instead that requires to have a team dedicated to a header because of the size of the complexity of that specific header when they work globally.
Luca:
Think about the large e-commerce that they use to buy stuff.
Luca:
And that is so complex because different services in different countries with different languages, all the permutation is making that very, very complicated.
Luca:
So that could be a microphone tent.
Luca:
But the reality, majority of the time, 99% of the time, I would say it's not one of them.
Luca:
It's the simple components, OK?
Luca:
So it's just an element that you want to have, reuse, have the same look and feel, because components compared to microphone tents, one is microphone tents, as we said before, they are aiming for independence between teams.
Luca:
The other one is aiming for reusability.
Luca:
And as Neil Ford says, reusability is a form of coupling.
Luca:
Therefore, we don't want to have components, but we want to have distinction between these two elements.
Luca:
So this one is basically baked into, it's a component baked into the application shell.
Luca:
At that point, when I'm basically going to these localhost 2000, I'm loading the first microphone tent, this home page.
Luca:
As you can see here, I also, let's say, highlighted, which is the version of the microphone tent, this is React 17, because I want to show you one thing in a second.
Luca:
This one is composed by a bunch of things.
Luca:
Marketing hero, banner, bunch of products.
Luca:
When I select one product, click the product.
Luca:
At this stage, for you, it was instantaneous.
Luca:
You didn't feel it, not because it's localhost, it would be instantaneous also on the web.
Luca:
What happens is basically loading a new microphone tent and possibly sharing certain dependencies.
Luca:
That is completely transparent for you.
Luca:
There are frameworks that enables you to download a React version once and reuse across all the microphone tents or only the microphone tents that acquire that version.
Luca:
In this case, we have React 18, so we downloaded a new version of microphone tents, but they are living exactly in the same application.
Luca:
For you, the look and feel looks the same because you're using the same design system.
Luca:
You have exactly the same thing that you have in the past.
Luca:
But the cool thing is that here we have two levels of, let's say, navigation.
Luca:
The first one is between first level URL, as it's called, so hard navigation between home to catalogue.
Luca:
We are changing domain, so therefore we are loading a new microphone tent.
Luca:
Inside the catalogue, the team responsible for that will be responsible for having the full view of the product that are available and the specific view on a specific product.
Luca:
It could be that they have also the review that is owned by a different, if you are a large team, you can have the customer reviews that are coming from a different team.
Luca:
Therefore, it could be microphone tents.
Luca:
If you have a simple e-commerce, it's more than enough having a component.
Luca:
Those are just components that you can reuse in multiple parts of your system, but it's reused inside the same team, the same, let's say, area of the application.
Luca:
That, I believe, is one of the power of these things.
Luca:
I can evolve this stuff in the way that I want.
Luca:
I can drill down and expand the capabilities of my catalogue, adding more second, third, fourth layer of URL, and drilling down with a complex routing mechanism while the application shell takes care about the global navigation, that is basically the first level URL.
Luca:
Now, when I move, for instance, in my accounts now, the cool thing is that I have React 17 and React 18 that are already loaded because I loaded them before, but they can't even live together.
Luca:
This is a classic example when you are migrating or when you are working with different teams.
Luca:
In a distributed system, the coordination is the part that you suffer the most between teams because it's very difficult that you can say, okay, so now stop everything.
Luca:
Don't deliver that feature because we need to update a version of React, Angular, whatever.
Luca:
Therefore, what you can do, though, is isolating, doing scope creep with multiple approaches, but this one is the one that I choose for this application and say, okay, these both will work together because they are not sharing specific data, but just, let's say, an object that is read-only and is vanilla JavaScript.
Luca:
It doesn't matter the framework.
Luca:
Now, if I want to communicate between the two microcontents, like in this case, when I click make default, you have this toast element that is at the bottom.
Luca:
This is a component that is living inside the application shell because it's generic.
Luca:
It doesn't have to be lazy load.
Luca:
It has to be there because multiple elements can use this.
Luca:
The thing that happens is what would you do in a microservice application if you want to, let's say, avoid point-to-point communication?
Luca:
You start to think about having a PubSub because a PubSub enables you to publish an event and one or multiple subscriber will react to that.
Luca:
Same thing with microcontents.
Luca:
Instead of having, let's say, a global state that maintains the state for everyone and where everyone can write and change potentially certain things, you just send an event that has a body.
Luca:
If you think we are getting closer to a certain extent of messaging architecture, you start to look into that part there, where in JavaScript it becomes extremely simple because now I have this element that is easy to test because I know that these, let's say, subscribe to certain events, so I can generate these events and see how it behaves.
Luca:
As long as when I push for production, the other microcontents are doing the same thing, then suddenly everything will start to work very nicely because everything is independent in the testing phase, in the design phase.
Luca:
There is a little bit of coordination, obviously, because maybe there is a new design system that changed, some breaking changes, whatever it is, and they require these things.
Luca:
But if you start to think about the effort
Luca:
where you design carefully
Luca:
what are the touching points for the company
Luca:
and when there are touching points,
Luca:
you create mechanisms, request for comments,
Luca:
architecture decision record, events that are typed
Luca:
and are capable to be shared across the system,
Luca:
you start to see that this area of design,
Luca:
the social technical system,
Luca:
generates a very simple architecture
Luca:
because now if I'm responsible for payments as a team,
Luca:
I will be responsible for the API of payments,
Luca:
I will be responsible for the integration,
Luca:
probably when I'm subscribing
Luca:
or the checkout phase for payment,
Luca:
I will be responsible for this view
Luca:
that basically enables me to change the thing.
Luca:
So now my team responsible for payments, we know inside out that domain, we'll be domain expert with that, they can contribute with the products people to create a better user experience and a better UI with the designer.
Luca:
And moreover, they can take the right decision for the job where very often we try to operate in economy of scale because we don't have enough bandwidth or people to cover the extent of a specific complex system.
Luca:
Now, if we start to look into this approach, now you see that your role as architect or platform engineering, et cetera, is supporting all these teams in a way with, let's say, common practises that will enable them to work together closely, but without being coupled.
Luca:
Because if sending an event is easy to test, as long as everyone respects that event, I don't have to coordinate with others.
Luca:
If I need to add a new microphone tent because there is complexity arise or a new domain that we need to squeeze inside this view, but then become easy because if I know what are the events that are bubbling around this view and the events that are available in the application shell, I just add new stuff.
Luca:
Even if I add the new events, I can add the new events, start to send it.
Luca:
The worst case scenario is no one is listening.
Luca:
There is no error happening inside the JavaScript.
Luca:
It won't block your application at all.
Luca:
And you can also have a lot of nice logic on, okay, I'm interested in that event.
Luca:
And then you can start to have, okay, can I have also this information with this other team?
Luca:
So you create a request for comment, you express what you need to have, and the other team can validate your request.
Luca:
And you see that now we start to look into holistically on the system.
Luca:
It's not anymore I implement React and I use this stuff.
Luca:
Now we want to encapsulate, and the terms encapsulation includes data and methods.
Luca:
It's not just UI.
Luca:
So if you start to think about that, my payment methods is encapsulating all the knowledge about payment of that specific user.
Luca:
In this case, there is no leaks.
Luca:
And if it needs to communicate on something that happens, can communicate passing the title and the description of what happened with this specific action.
Luca:
But the action itself can be reused by other place because you design in a way that is agnostic from the domain because it's living inside application shell.
Luca:
A lot of these thoughts that I described, that I'm showing you here, are basically the process that enables you to create independent teams that reduce the extent of dependency, don't eliminate the extent of dependencies, but just reduce them.
Luca:
And they have more control and power on making change without interfering with other massive release that could happen.
Luca:
Then in my experience, once or twice a year, sometimes four times, of course, if you have a very fast pace place, you are required to have something that's spanning across a new feature that's spanning across multiple domains.
Luca:
So in this situation like that, there is the requirement of coordinating multiple teams, trying to understand how these things will pan out in terms of contracts.
Luca:
And in this case, what kind of teams will be affected into that.
Luca:
I was in that scenario very often.
Luca:
But if you play very well your role as, I don't know, staff engineer or group of the virtual team that is working on the design or architects, whatever is available inside your company, then you start to see some interesting pattern that if you design properly that chunk, the implementation will become a breeze because it will be part of the patterns that you have already created.
Luca:
And if you have a new pattern to integrate, you will have the possibility to test with a chunk of the system without affecting all the rest.
Luca:
So the complexity is there because you need to think holistically on the system.
Luca:
But at the same time, the reward is there as well because I have, let's say, my previous company, what I was working for, for this company called The Zone, a staff engineer that I met last year told me it's eight years that we are working with this architecture.
Luca:
It never went through our way.
Luca:
We were able to, let's say, change the things accordingly for what the business wanted because of your principles and, let's say, design that enables us to be flexible where it was needed to be flexible and then force boundaries and generate friction where it was needed.
Luca:
And I think that was the testimony that design is still an extremely important part of software.
Karol:
Okay, Luca,
Karol:
so to recap a little bit here,
Karol:
so the approach is
Karol:
as if with a microservice system,
Karol:
any microservice system,
Karol:
we're looking at having high cohesion
Karol:
within a microservice
Karol:
or a group of microservices
Karol:
that are bound to a specific domain
Karol:
or subdomain,
Karol:
however you want to name it
Karol:
using domain-driven design
Karol:
or just plain language,
Karol:
so that within that cohesion,
Karol:
you have a full understanding
Karol:
of the problem space
Karol:
like payments or like catalogue
Karol:
or like if needed,
Karol:
the top bar of the website.
Karol:
And that's the high cohesion.
Karol:
And then looking at the distance
Karol:
between different domains,
Karol:
so either groups of microservices
Karol:
or a singular microservice
Karol:
and the teams governing them,
Karol:
then we have a higher distance
Karol:
between those two,
Karol:
so we don't need that shared knowledge
Karol:
as long as we describe the contracts well,
Karol:
whatever those contracts may be,
Karol:
here being like with microservices,
Karol:
either API calls or events,
Karol:
if we do PubSub event-driven architecture
Karol:
exactly like with a microservice system
Karol:
because it's very nice
Karol:
to combine microservice systems
Karol:
with event-driven architecture.
Karol:
That's a very common thing that happens architecturally.
Karol:
I'm curious because I've never been a front-end guy.
Karol:
I mean, I do write a little bit of HTML, but that's the extent of my front-end knowledge because I mostly write it for all sorts of plugins that I do in my Google workspace.
Karol:
So front-end is completely not my thing.
Karol:
I'm more of a, well, middleware engineer, not even a back-end engineer in that sense.
Karol:
So I only utilise front-ends rather than build them.
Karol:
I'm curious, could we dismantle this in a diagram to show lines and boxes and where does that communication and what type of communication does happen here?
Karol:
If you even take the example of Fred's Tales, which is this demo site that you have, perhaps we can use that and you can then reiterate on this using some diagrams.
Karol:
Would that be a good idea right now?
Karol:
Yeah, that's fine.
Luca:
Do you share the screen or should I share the screen?
Karol:
Yes, I'll pop in.
Karol:
So if any of you watching, we're currently live on Miro.
Karol:
I'll post the, I'll copy the board link and put this in chat on YouTube.
Karol:
There we go.
Karol:
And also we'll do this on LinkedIn if you want to follow us on the board.
Karol:
Otherwise, I'll just follow Luca.
Luca:
Yeah, so let's try to, let's try, oops.
Karol:
Diagramming in Miro, yes.
Luca:
Yes, exactly.
Luca:
So let's try to do one thing.
Luca:
So this one was user details.
Luca:
Let me increase a bit because otherwise everyone will hate me and we are near Christmas.
Luca:
So at least we can say that we did good.
Luca:
And this one was payment.
Karol:
Just for the sake of Santa not putting us on the list, right?
Luca:
Yeah, exactly.
Luca:
I don't want to be the naughty boy, the naughty architect.
Luca:
Could be the next title that I could use, the naughty architect.
Luca:
And then we have here the application shell.
Luca:
Sorry.
Karol:
Question, what do you get in Italy?
Karol:
What do you get from Santa if you're naughty?
Luca:
Nothing.
Karol:
In England, that would be a lump of coal.
Luca:
Yeah, that could be that.
Luca:
But usually it's for us, the 6th of January, there is the befana that I know is very specific for us.
Luca:
And it brings usually, if you are a naughty boy, you have the coal.
Karol:
Okay.
Karol:
In Poland, this is a stick.
Karol:
A stick to whip.
Karol:
A flexible stick that we get if we're naughty.
Karol:
All right, so this is the shell.
Luca:
This is our situation, right?
Luca:
Then we will discuss about the interoperability with the services because also there are interesting discussions.
Luca:
So the first thing is, I don't know how to draw that.
Luca:
Let's assume that we can do in this way.
Luca:
So you have like our object that could contain some configuration, okay?
Luca:
That is owned by the application shell.
Luca:
This is, let's say, the first element.
Luca:
Ideally, it's not always the case.
Luca:
Not everyone is implementing that way, but ideally, this should be read-only and is a property like it tells you.
Luca:
Majority of the time, you have like, I don't know, feature flags.
Luca:
You have maybe some URLs that you need to provide dynamically.
Luca:
Sometimes, for instance, I've seen some companies passing the user data into either the HTML or exposed as an object inside the page.
Luca:
I remember when I did the request engineering 10 years ago on Netflix, they were basically adding the user data inside the JSON object inside HTML in order to avoid to make another code.
Luca:
That was a smart way for optimisation, but there are plenty of ways that you can do it.
Luca:
But usually, you have a configuration of some sort.
Luca:
The other thing is, at this stage, I can retrieve some stuff.
Luca:
You will have, majority of the time, let's see if there is more shapes.
Luca:
There is the document shape.
Luca:
My shape, I don't know.
Luca:
Yeah, there is AWS stuff, obviously.
Luca:
Okay, let's assume.
Luca:
Let's take this.
Luca:
This one?
Luca:
Can I take this?
Luca:
No, I need to upgrade, so I cannot.
Luca:
Let's take this.
Luca:
Okay, perfect.
Luca:
So then you have, majority of the time, a cookie that is your session.
Luca:
This is available to everyone, right?
Luca:
So the cookie is something that is, as long you configure it properly, because the security model of the cookie is that you can set up different subdomains there.
Luca:
You can say www.payment.mysite.com will have this cookie, so the cookie will be accessible by every single domain.
Luca:
There are a bunch of other, sometimes you have a database that you can have on local storage, session storage, or even a web database that is available inside your browser that you can use.
Luca:
Those two things are accessible globally in JavaScript, so you don't have to do creating any fancy stuff unless you want to, but these are usually the things that are accessible.
Luca:
So basically, every micro-frontend will have access to the configuration.
Luca:
99% of them will need that.
Luca:
Cookie, if you are in an authenticated situation and or local storage, session storage, web storage, whatever it is that you want.
Luca:
Those are the things that everyone has available.
Luca:
Now, if I want to communicate with the application shell or with the payment, what you usually do is having this emitter.
Luca:
This one is, let's see if I can increase this.
Luca:
Boom.
Luca:
Okay.
Luca:
You have this emitter that is a singleton, so you have just once in your instance, just once, and then you inject inside every micro-frontend, but the idea is that now my micro-frontend can, my direction probably is better, can send an event to or receive an event from an emitter and say, okay, I send an event that, I don't know, the user detail changed.
Luca:
I need to show a pop-up, and therefore the application shell in this case will have a component that subscribe to the, let me see if I can do this, that subscribes to, how do I do a pop-up here?
Luca:
I could build this one.
Luca:
Okay.
Luca:
That subscribe to the specific event that is, let's create the event.
Luca:
It's called, let's see, onUserChanged.
Luca:
Something better maybe, but let's use it.
Karol:
That's a listener more.
Luca:
Yeah, sorry.
Karol:
Yeah, userChanged, I suppose the event would be then.
Luca:
UserChanged, then what happens is, you send these events, then the pop-up will have that onUserChanged.
Luca:
Basically, we receive these events and we'll behave in certain ways of showing the pop-up and then allowing certain things.
Luca:
The userChanged obviously can have an object with some details that it can use and that are useful for the pop-up, either for retrieving certain information and other things.
Karol:
That's basically miniaturised, event-driven approach.
Luca:
Correct.
Luca:
It's literally a pop-up system.
Luca:
If you think about that, JavaScript is already event-based.
Luca:
I click a button, a dispatching event.
Luca:
The problem you have with JavaScript events, that is a problem I sorted out a long time ago with a technology called Flex that was part of the Flash platform and that shows how old I am.
Karol:
I still remember Flash.
Luca:
Missed it dearly.
Luca:
The problem there is that even in JavaScript, you have a DOM structure that is basically a tree.
Luca:
I can have different branches.
Luca:
Let's assume that we have two branches.
Luca:
This one is living inside a branch and this one is living in another branch.
Luca:
If I use dispatch event in JavaScript, in order for me to listen to payment without referring to payment, because otherwise I create coupling, I know that today there is payment, tomorrow there isn't, so I need to change twice, so you don't want to do that.
Luca:
But during that time, what you do is doing this.
Luca:
So you do window.addEventListener. So registering the listeners to somewhere.
Luca:
Why that?
Luca:
Because this one is the top object that's composed of the browser, so for sure we'll arrive there.
Luca:
The problem is the for sure part, because in JavaScript, I can also have inside my payment an object that what it does is, or a component, that is a higher level component that has, what is it?
Luca:
Searching.
Karol:
But it's further in the tree.
Luca:
It's in between the payment or the component that dispatch that event and the window, and basically we'll do, these are the user change, you will have my function, my function, and inside my function, you can have a nice event, so preventEventDefault, if I remember well the method, and this will basically stop the propagation, and therefore it will never arrive to Windows.
Luca:
Edge case.
Luca:
When happens, good luck debugging.
Luca:
So instead, this is a way that is completely abstracted to any framework.
Luca:
That works, it's like pure vanilla JavaScript.
Luca:
This is usually an emitter, it's an observer, not an observable, an observer pattern.
Luca:
So I have an array of objects that are subscribing to a certain event.
Luca:
When I emit an event, it's just taking the array part, going through the entire array, and say, on method, and then dispatching this specific event.
Luca:
The beauty of this approach is completely agnostic from the position, so if tomorrow I nest payment in a different way or as part of another microcontent, whatever it is, it doesn't really matter, as long as it has the instance of emitter.
Luca:
So this approach simplifies drastically the way how you deal with not having to think about, oh, now I have, let's say, a potential issue that could happen.
Luca:
I don't know when it happens, because obviously at the beginning we all know we are extremely, let's say, pumped on applying all the best practises, but then when we have the first thing that you need to deploy for tomorrow because otherwise there's a problem, then you start to implement and cut corners everywhere.
Luca:
And usually, even if you cut corner, you don't crash.
Luca:
That's basically the idea.
Karol:
Yeah, because the tree structure makes it difficult.
Karol:
I don't really get to experience that because I don't get that level of events in anything I write in JavaScript, but if I can make an analogue in my head in what I do, it's basically where I put the variable in my code matters in the tree structure.
Karol:
So this is exactly the same aspect.
Karol:
If I put the definition of the variable very low in the tree, close to the root of it, then it's accessible to a lot of things in the code.
Karol:
But if I define it somewhere further in a loop or in an if statement or anywhere else, then I will have a problem because it will not be visible to the other parts, and then I need to rethink all of this.
Karol:
And this is exactly the same issue, but at a different scale.
Luca:
Correct.
Luca:
That's the challenge.
Karol:
Yeah.
Luca:
And this one is the communication that's happening inside the browser, basically, majority of the time.
Luca:
Right.
Luca:
Now, there is a communication towards the backend.
Luca:
And here we have a variety of possibilities.
Luca:
We can have GraphQL as an approach.
Luca:
So I expose, like, GraphQL.
Luca:
Why GraphQL for frontend makes a lot of sense?
Luca:
Because if you have a majority of the,
Luca:
let's say, application nowadays
Luca:
are on mobile, are on web,
Luca:
sometimes in other devices,
Luca:
and the thing that I can query,
Luca:
let's say, GraphQL,
Luca:
with information that I need
Luca:
only for that specific screen,
Luca:
reduce the chattiness,
Luca:
I can design the things in a better way,
Luca:
I download way less code
Luca:
that is not needed,
Luca:
especially the mobile teams
Luca:
are extremely happy
Luca:
when there is GraphQL on that.
Luca:
And there is a caveat, but we will discuss in a second.
Luca:
And in general, you know, it's a great way, very, I would say, quite democratised nowadays.
Luca:
It's not that you need to get crazy on that.
Luca:
There is a very nice level of sophistication now in certain implementation where you can even have security on what you see based on the token or based on the role of the user.
Luca:
So there is, let's say, quite a lot nowadays.
Luca:
The beauty of this approach now, especially in the last few years, is that you have this idea of, what do I use?
Luca:
This one probably.
Luca:
Schema federation.
Luca:
Where, if you think about that, I have multiple teams that are working on an application.
Luca:
We decide that we slice in a certain way our front-end and our back-end.
Luca:
Now, suddenly you are introducing a single point where every single request is passing through.
Luca:
How can I maintain the independence of teams?
Luca:
And GraphQL come up with this idea of schema federation.
Luca:
This idea where I create my own schema for describing my own domain.
Luca:
And then GraphQL is creating a super graph that is bundling everything together.
Luca:
So I have it for front-end, it's a unique layer that I get access to.
Luca:
But for the back-end, I can evolve things in a way that are completely independent.
Luca:
Okay.
Karol:
So for those who are versed in domain-driven design, for me, this sounds like GraphQL created an open host service with published languages based on whatever is the domain you're trying to work.
Karol:
And that schema federation works as the repository of those published languages.
Luca:
Correct.
Luca:
So the cool thing of the schema is that you think about, you create a schema, and I need to consume that.
Luca:
You create one, and then another person will create another one.
Luca:
And somehow I need to find myself that they can combine different domains because the domain on front-end might not be the domain on back-end.
Luca:
In the previous example, for instance, you probably have a user domain and you have a payment domain.
Luca:
That would be some foreign tables, some communication between these things, depends from the complexity that you have.
Luca:
But the reality is these two things will be distinctive.
Luca:
But in the front-end, we want to show both.
Luca:
And therefore, as you can see now, you are in a situation where you create something ad hoc.
Luca:
For instance, GraphQL won't require that because you have the availability of multiple domains available for you, and that could be okay for certain companies.
Luca:
In certain scenarios, though, there are, let's say, if you start with REST APIs, you want to keep REST APIs because the problem is not that GraphQL will create technical challenges, but will introduce philosophical issues inside your system because the way how GraphQL, let's say, democratise the information is maybe something that you want to do on a certain part of the system.
Luca:
At the moment that you introduce something like that, in six-month time, I can guarantee you that happens more than once, someone will say, but that team is using GraphQL.
Luca:
Why cannot we use the same because we have a similar problem?
Luca:
And that opens up a door of different philosophies, different way to update APIs, different ways to consume APIs, different way to scale infrastructure, and that can go ahead forever.
Luca:
So for me, it's very, very important that when we, at the beginning of the discussion, we were saying, guys, let's try to think and design things in a certain way.
Luca:
You look into this problem and understand, okay, GraphQL, it's something that we want to embrace.
Luca:
We know the trade-off, what they are, so we democratise the information.
Luca:
Is it fine for what you need to do?
Luca:
Because then if you have high volumetric and it requires, let's say, I don't know, you have a million requests every second, then you need to scale horizontally.
Luca:
It's totally doable, obviously, but one thing is, let's say, handling, let's say, one service that has to scale, I don't know, 200,000 requests per second.
Luca:
One thing is scaling one that is a million, and if it's down, basically the whole system is down, right?
Luca:
So you need to be careful on how you design these things.
Luca:
You can potentially think about a back-end for front-end approach that is domain, let's say, divided by domain.
Luca:
That could be another approach that you can think about where you just basically have the possibility to not having a schema federation.
Luca:
You just have a REST API that aggregates a bunch of APIs from different domains, potentially, or the same, up to you.
Luca:
But then it means that I will have a proliferation of those, so one per domain, and a BFF.
Karol:
If you are actually partitioning per domain, because I would argue that depending on the maturity of the organisation, the maturity of the teams, you may just have a single BFF that will handle all sorts of domains because you haven't even thought about the main partitioning at this point just yet.
Karol:
You have more of a functional partitioning and technical partitioning rather than actual domain partitioning.
Luca:
For me, you know, because in my experience, there are, I can tell you, in my previous job, for instance, we used one BFF for one domain that was my account for not having to deal with exactly this problem here.
Luca:
Because when you have one microcontents, you need to create governance into that.
Luca:
Who is responsible for end-to-end testing?
Luca:
Who is responsible for integration?
Luca:
Who is responsible for making sure that we need to define these API, these events, and therefore everything will work?
Luca:
Who is creating the, so there are a lot of who is creating, so the ownership part becomes complicated.
Luca:
So how I solve that is say, okay, I can have two teams responsible for that or I can have a BFF for my account, let's call my account here, that includes payments and user details and whatever else we had in the past.
Luca:
So now that this team is responsible for one microcontent, okay?
Karol:
That services two, yeah, that services different things.
Luca:
It is super simple.
Luca:
The domain aggregation is done at the backend and still the same team is responsible for these things.
Luca:
And they remove all the complexity on governance.
Luca:
Right.
Luca:
So I was the only domain that needed this specific treatment, introducing GraphQL like it was asked from developers or let's say handling microcontents differently, but then having all the complexity on updating and all the other stuff, I resolved in a very simple way.
Luca:
I created a backup from front of my account.
Luca:
The API weren't changing very often because I check the code volatility of these API.
Luca:
So the contract remained fairly stable.
Luca:
Also because we have, let's say, payment APIs are delicate in general and user are the same.
Luca:
When you define user, usually you augment the API.
Luca:
You don't do too many breaking changes in a year.
Luca:
So code volatility wise, we were fine.
Luca:
And that enabled me to have, let's say, a single point where I aggregate all the information.
Luca:
The team was responsible to switch when needed the right version of the API to consume.
Luca:
And the microcontent, it will have always the same, let's say, contract.
Luca:
So it will be a team, very easy to maintain that microcontent.
Luca:
The only thing that needs to take more into account is the backend for frontend.
Luca:
So as you can see now here, the decision, it wasn't, oh, let's play with GraphQL.
Luca:
It's trying to figure out what means for me in terms of trade-offs if I have multiple microcontents in the same view and analyse what is the benefit of instead introducing a middleware and disaggregating the data, because in reality, they're not changing very often.
Luca:
And the traffic on that specific area, my account, if you think how often you go to my account in Netflix, it's probably once a year when your credit card expire, when you want to change your email, stuff like that.
Luca:
So it wasn't, let's say, the complexity wasn't worth it for the domain that I was designing at the time.
Luca:
That's another key takeaway, in my opinion.
Luca:
Very often, again, we're not playing with best practises or amazing tools or bleeding edge tools, but we reason around what is the trade-off that really makes shine that specific context, because context is king.
Luca:
They can provide the best effort without, let's say, create too much complexity.
Karol:
So basically here, we not only have a trade-off analysis
Karol:
over, let's say, the functional aspect of this,
Karol:
because we have the scope of usage, the volatility,
Karol:
which is one of the degrees of coupling,
Karol:
as described by Vlad Kononov,
Karol:
but also we're looking at the socio-technical aspect
Karol:
of what is the trade-off then,
Karol:
from a socio-technical perspective,
Karol:
over responsibility, accountability,
Karol:
of different tasks around the whole lifecycle
Karol:
of these components.
Karol:
So development, making changes, maintaining this, testing this end-to-end, and all other aspects of communication between teams.
Luca:
As I was saying at the beginning, the whole point that I started with, the principles behind a micro-frontend, and one of them is being dependent, that was my north star to follow.
Luca:
Therefore, if I design things without thinking
Luca:
what is the impact of my developers
Luca:
holistically, in terms not only on cognitive load,
Luca:
but also what is the effort, what is the governance
Luca:
I need to create, what the platform teams need to do,
Luca:
there are extra new things that we need to think about,
Luca:
think about ownership and stuff like that,
Luca:
I'm making a disservice to the company,
Luca:
because, again, it's not architecture that is failing,
Luca:
it's you that you are, let's say, simplifying too much
Luca:
the complexity of building software
Luca:
in a distributed system,
Luca:
because a distributed system has a complexity
Luca:
that is in three dimensions always for me,
Luca:
architecture, engineering, culture,
Luca:
and team topology, so organisation structure.
Luca:
If you're not seeing these three dimensions holistically
Luca:
when you do trade-off analysis,
Luca:
then you are basically taking a guess
Luca:
that you might have the right decision or not,
Luca:
and then blaming architecture
Luca:
because there is friction inside the system
Luca:
without understanding that this friction
Luca:
is the way that architecture
Luca:
or a social technical system has
Luca:
to tell you, by the way,
Luca:
you didn't think about the other dimensions.
Karol:
I like to refer these kind of points to Tesla's law.
Karol:
You probably know Tesla's law because this is a very common law used in user experience.
Karol:
I personally use this for system-to-system interoperability because it's still very much applicable, and Tesla stated that there is an inherent amount of complexity in the problem domain that is irreducible.
Karol:
We can add accidental or additional complexity to it by over-engineering, by over-complicating, or over-simplifying a problem.
Karol:
That complexity, the question is who is going to handle that complexity?
Karol:
Basically, what you're saying is it adds degrees to where that complexity can go or derive from because it can derive from architecture itself, it can derive from the engineering culture and the team topologies to the organisation itself or go to those places if it's poorly addressed in any of those categories that you mentioned.
Luca:
Completely, because if you see this example that I made on purpose, this approach is technically sounded.
Luca:
And similarly, the approach technically works because I'm maintaining the separation of concern between the elements.
Luca:
Now, the problem is in a vacuum.
Luca:
Both will work and will be well-designed.
Luca:
But if you start to add a new layer
Luca:
that is the context,
Luca:
so the business requirements
Luca:
and the architectural characteristics
Luca:
and the engineering culture
Luca:
and the organisation structure,
Luca:
now you start to say,
Luca:
but probably this makes more sense
Luca:
because looking at the vacuum
Luca:
on the technical solution nowadays,
Luca:
especially in distributed systems,
Luca:
is, let's say,
Luca:
being a bit blind
Luca:
on the reality of the case
Luca:
because if you are not capable
Luca:
to have a full understanding
Luca:
of the system,
Luca:
it's very difficult,
Luca:
and the context is very difficult
Luca:
to say this is the direction of travel.
Luca:
As an AWS specialist, what I'm doing is jumping in a customer that I maybe never speak with and that half of my discussions is around organisation structure and what you're trying to achieve, what are the goals that you have, what is your volumetrics, what is your availability goals, stuff like that, that they know will impact whatever I'm going to say after that.
Luca:
And usually after 40 minutes that I'm talking about all of this, in 20 minutes I can solve the problem because now I have all the context of the world and I can tell you, listen, you are doing this, but the problem you have is that if you're telling me that your teams are doing this, that probably what you are implementing doesn't work.
Luca:
Either you change the way how you structure the team or you change the way how you implement these things because otherwise friction will arise anyway.
Luca:
So it's not a problem of technology, it's a problem of that you didn't think holistically on a specific part.
Luca:
And that's why, let's say,
Luca:
in the last 10 years
Luca:
I mastered a lot
Luca:
of this kind of multidimensional vision
Luca:
as architect
Luca:
because it enables me
Luca:
to look at things differently
Luca:
from a developer
Luca:
that unfortunately
Luca:
they are forced to look
Luca:
into their chunk of the system
Luca:
and therefore they master that part,
Luca:
they are extremely proud of their craft,
Luca:
but they don't, let's say,
Luca:
take a step back
Luca:
and look, okay,
Luca:
what are we trying to achieve here?
Luca:
And that's where I believe more senior people like staff engineers or architects or engineer manager, whatever, should provide that information to feed inside the teams for taking better decisions.
Karol:
There is a quote attributed to Einstein that Einstein, when asked, at least supposedly, if he had one hour to save the world, what would he do in that one hour?
Karol:
And the quote is that he would spend 55 minutes understanding the problem and five minutes actually saving the world and fixing whatever is wrong.
Karol:
And I found this, I believe this exact attribution to the quote was somewhere in the book I was recently reading, a very nice one, domain-driven refactoring.
Karol:
And basically, in the book, they touched, because refactoring is also a psychological problem, they touched upon what you already hinted at for the perspective of developers.
Karol:
Developers, or engineers in general, they hate to be in the problem space.
Karol:
They like to be in the solution space.
Karol:
Oh, we see a problem, we jump to solutioning.
Luca:
Exactly.
Karol:
And that's from a perspective of business or from perspective of architecture, that's pretty much the worst thing you can do.
Karol:
Because then you have a solution that doesn't really fit the problem and it doesn't really solve the problem because it didn't take enough time to understand what the problem is and potentially the solution should have been a lot simpler.
Karol:
Yeah.
Karol:
So already by solutioning instead of architecting, we jump into making assumptions.
Karol:
And that's always going to be painful to a certain extent.
Karol:
And this is why this kind of trade-off analysis and also looking at the other axes of the problem like engineering culture or the organisation or team topologies, the dynamics between teams, it's crucial to build a proper architecture.
Luca:
Absolutely.
Luca:
And that's why, honestly, what I'm trying to do is democratising this approach and trying to provide a distilled version of all the things that I discussed so far in my book in order that they don't have to do what I have done and they can, let's say, apply these things properly.
Luca:
In my book, I spent plenty of time to describe migration, the status of the specific context that I was doing and stuff like that mainly because I want to, let's say, start to make them sensible on these topics because it doesn't come for free.
Luca:
Very often, I have seen that teams blame me from time and when they maybe try in the field and then they start to speak with me and I start to dig deeper into the topic and I explain to them, oh, yeah, but your friction was generated by that from what you're telling me.
Luca:
I say, oh, yeah, you're right.
Luca:
And then they give a second chance.
Luca:
The second chance usually is successful because if the mindset is not because I'm ingenious or I'm better than others, I'm definitely not.
Luca:
I'm definitely an average person.
Luca:
But the thing is, what differentiates me is that I start to look holistically on these things.
Luca:
And everyone can do that if I was able to do this.
Luca:
But the thing is, you need to understand that the problem space is bigger than what you expect.
Karol:
Mm-hmm.
Karol:
That is definitely true.
Karol:
Usually, in general, the majority of the problems we have in IT are not technical problems.
Luca:
Yeah.
Karol:
We need to solve them on the level of a conversation with our stakeholders, conversation with our business to understand what is the actual business need.
Karol:
Not the business wants, to be precise, because the business will say what they want, which is not precisely what they need.
Karol:
And for us as architects, this is the part where we can step in to actually translate what they want from us into what they actually need to be built and developed and then we need to figure it out how it is supposed to be done.
Karol:
And this is the difficult part because this is where we as architects really don't need that technical knowledge.
Karol:
We really need a lot softer skills, right?
Karol:
Conversation, capturing nuances, discovering things, being pretty much business analysts.
Karol:
And that's for a lot of people, it's very difficult, especially if they're just beginning their journey into architecture.
Luca:
Oh, yeah.
Luca:
Yeah, it's a role that you grow in more than you're ready and you just, let's say, start to do that.
Luca:
You need to push outside your comfort zone very often and definitely technical background helps because you have, let's say, already one part of the problem in your head.
Luca:
You don't have to be, let's say, the best developer in the world, but definitely having a bit of background, in my opinion, helps because you have, let's say, a portion of the system there.
Luca:
Then I was lucky enough to be in a situation where we needed to move fast and I have the possibility to look into the other two dimensions.
Luca:
And that's where probably, let's say, nowadays, I'm more confident to say this is going to happen or this is the right solution because I was able to see them firsthand.
Karol:
Yeah, I think that experience you had over this fast really quickly growing company, I think that really shapes.
Karol:
Like me, if you work in consulting and you're exposed through projects just to a small snippet of the problem space, it's a lot harder to grow into the role of an architect that way because you don't have to tackle all those aspects.
Karol:
You just tackle what you're served in terms of tasks in Jira or whatever other system that you agree on the scope of work.
Karol:
And that's very problematic for people to grow out of that mindset and to look at the broader picture, to have that holistic view of what's going on.
Karol:
And this is something that is really needed.
Karol:
And I learned that kind of the hard way, but I also had, through reading the works of Mark Richards and Neil Ford, that really helped me further develop that view into architectural thinking instead of being narrow-minded into that technical thinking because it created more friction for me than it needed, really.
Luca:
Yeah, totally.
Luca:
I think when I had the possibility to jump from product to consulting, I always said no for a certain period of time because the challenge you have usually is if you work in product, you take some shots and some decisions.
Luca:
But before you see the impact of your decision, it would take probably between six to 18 months from when it's in production.
Luca:
Before that, it can be as good as it could be, but the reality is you learn, you need to play the long-term, long game in architecture because the more you see things that, okay, I decided this, this was the context, this was the situation, these are the outcomes.
Luca:
These are all baggage that you usually have.
Luca:
In consulting, the vast majority of the time you arrive to deployment of a solution, you see a chunk of the system.
Luca:
If you are lucky, you have a contract that is long enough to see these things, but it's not given for granted, while if you are internally in the product, you evolve the product over and over again and that you see all your decisions right or wrong or right for the context that has to be changed, but you have the context of why you take that decision at that time.
Luca:
Luckily, maybe you also documented in your architectural decision record, but then you have the possibility to iterate into that based on the involvement of the social technical system.
Luca:
And that, for me,
Luca:
is where really you learn
Luca:
how to do architecture,
Luca:
let's say, properly
Luca:
because very often,
Luca:
if you just, let's say,
Luca:
move from one project to another one,
Luca:
you will have a lot of breadth
Luca:
of use cases,
Luca:
but you are not going to see
Luca:
if your decision will have
Luca:
right or wrong impact
Luca:
because of a variation
Luca:
with consultants
Luca:
that are telling me,
Luca:
oh, I was doing that
Luca:
and then it turns out
Luca:
that some of them
Luca:
was one of my customers
Luca:
in AWS.
Luca:
And when I spoke with them, we were saying, oh yeah, this consultant did that, but basically after they left, they left a mess because they were incapable to scale at the level that we needed and then basically they call other people to fix that and they validate with us.
Luca:
So this situation happens over and over again.
Luca:
So I think it depends in which, let's say, part of your career you are at.
Karol:
I was lucky to move back and forth between consulting and being in-house, so I have the two perspectives.
Karol:
And it really depends on what you need right now in your career.
Karol:
Sometimes you need the breadth of knowledge to experience different technologies, experience different projects, different types of projects, because you got bored by your in-house project, which is constantly in the same scope of business problems.
Karol:
So that's no longer interesting.
Karol:
Other times, it's really, really nice to see over time how your work actually impacts the organisation.
Karol:
And I remember this lovely part where I was still a junior developer working in consulting and then I moved to my client to have an internal role later as an architect.
Karol:
And I opened, that was back when subversion was still a thing, not Git.
Karol:
And I opened subversion, like, who the hell screwed this up so royally?
Karol:
And I saw four years earlier my name under those comments screwing it up so royally.
Karol:
And I was like, oh, okay, this is a growth moment, right?
Karol:
This is where the perspective comes in, kicks in, and now I have a proper understanding of what's going on.
Karol:
And this is important to put that context in.
Luca:
Completely.
Luca:
I think it's just a learning thing.
Luca:
So in order to become an architect, you need to design a lot of stuff, see the impact of your design, and it's easier to a certain extent if you spend a few years in the same place because you will have a better perspective because you understand the context.
Luca:
And moving between context, you can take away between context in terms of industries, potentially.
Luca:
You can take away a lot of your learnings and apply in different industries.
Luca:
But I did something similar like you.
Luca:
When I was living in Italy, I had my own agency, so I've seen a lot of, let's say, breadth at the beginning of my career.
Luca:
And when I moved to UK, instead I started to work more on product because I needed to go deeper.
Luca:
I needed to see the impact of my things either as a developer or architect, wherever it was.
Luca:
And that worked out
Luca:
until a few years back
Luca:
that I decided to go back
Luca:
in a certain way
Luca:
consulting in AWS
Luca:
because there I wanted
Luca:
to see where my depth
Luca:
and breadth was reaching
Luca:
the tipping points
Luca:
and see what I'm missing,
Luca:
what I didn't see
Luca:
or I didn't discover yet,
Luca:
and the possibility
Luca:
to work with large companies
Luca:
and large customers,
Luca:
obviously,
Luca:
was for me
Luca:
extremely important
Luca:
for my career
Luca:
and validate, basically,
Luca:
my learnings
Luca:
and learn new things
Luca:
that obviously
Luca:
was one of the key aspects
Luca:
for me to join
Luca:
a company like this.
Karol:
Yeah, these paths are crucial.
Karol:
It's crucial
Karol:
to have a little bit
Karol:
of a reflection
Karol:
over time
Karol:
where you want to go next
Karol:
and what you want to do
Karol:
and why,
Karol:
not just do random moves
Karol:
in your career
Karol:
because these moves
Karol:
will definitely shape
Karol:
your thinking
Karol:
and the way you do things
Karol:
and it's always
Karol:
a difficult choice
Karol:
in that sense
Karol:
because there are
Karol:
so many factors
Karol:
that go into that decision
Karol:
and your opportunities
Karol:
for growth
Karol:
from that perspective.
Karol:
So, yeah, and this later translates to these kind of lovely designs like microfrontends which is amazing.
Karol:
Okay, so if we had our microfrontends, we had the Shell app, we had different microfrontends embedded into that Shell app, we discussed GraphQL as a means of reading data.
Karol:
Do you use GraphQL at all for writing data?
Karol:
I don't think it's a thing.
Luca:
Yeah, potentially you can do also that.
Luca:
It's bi-directional completely so it's not a big deal.
Luca:
You can even have subscription that basically enables you to have a web socket under the hood and when one thing changes, on the back end, it will be displayed inside the UI.
Luca:
It's extremely powerful to be honest.
Luca:
I've seen a lot of the capabilities offered by GraphQL used with microfrontends or with monolithic applications but majority of the time I've seen successful implementation on multi-device approaches due to the nature that they can query whatever they want and now with schema federation was a big plus.
Luca:
Now microfrontends,
Luca:
we borrow the idea
Luca:
of schema federation
Luca:
where you compose things
Luca:
in a single schema
Luca:
creating a super schema
Luca:
and that's where
Luca:
you lazy load stuff
Luca:
and since I would say
Luca:
seven, eight years ago,
Luca:
we started to see
Luca:
a proliferation of frameworks
Luca:
that came out
Luca:
on microfrontends
Luca:
but now also
Luca:
the new frameworks,
Luca:
the server-side rendering one,
Luca:
the one that is usually used
Luca:
for e-commerce,
Luca:
the most famous one
Luca:
like Next.js, Astro.js, etc.
Luca:
They have microfrontends as first-class citizen inside their system because you can use what they call React Server Components or Astro Server Island that are basically implementation microfrontends.
Luca:
They have similar principles.
Luca:
They don't call microfrontends but you can build microfrontends with those.
Luca:
I have several examples
Luca:
in my GitHub repository
Luca:
with Next or with Astro
Luca:
just to show
Luca:
how you should think about it
Luca:
because the reality is
Luca:
when you understand architecture,
Luca:
you are in a position
Luca:
where it doesn't matter anymore
Luca:
if it's edge rendering,
Luca:
server-side rendering,
Luca:
client-side rendering,
Luca:
a desktop application,
Luca:
a mobile application, whatever
Luca:
because the logic is always the same
Luca:
as architecture at the end.
Luca:
It's not a framework.
Luca:
You are not bounded to a framework.
Luca:
You are bounded to, let's say, an approach.
Luca:
So for me, in the book I describe what I call the decision framework that basically are four decisions you need to make in every single architecture.
Luca:
Every time you design with microfrontends, I encounter this decision every single time.
Luca:
So how to slice a microfrontend?
Luca:
You want one microfrontend loaded per time, multiple of them.
Luca:
Obviously, they are non-mutual exclusive so you can choose certain domains you will have multiple microfrontends like the one that we show in the diagram.
Luca:
Some others, you might have a single microfrontend like the catalogue that I was showing in the demo.
Luca:
And it's fine.
Luca:
But then you need to think about how you route and how you compose.
Luca:
So you do on the client, you do on the server, you do on the edge because, for instance, I applied strangler pattern on the edge for migrating from a monolith towards the microfrontends in a very nice way because that enables me to pass through the CDN no matter what I do.
Luca:
Therefore, I can start to have some smart logic.
Luca:
I started to have kind of releases at the edge where I say, every time that you call this microfrontend and I have a new version, I want that 5% of the traffic goes with the new version only if they are in, I don't know, Germany and they are in Google Chrome.
Luca:
So in this situation, I can shape the deployment that basically the idea of introducing this was creating a safe net for developers to reach production more often because as the book Accelerate taught us several years back, we were looking into dollar metrics so we want to go as fast as possible in production because that is one of the characteristics that enables a successful company to succeed.
Luca:
And if you create a safe net for developers, they are capable to, for instance, this approach moved the needle from two free deployments per month to 25 per day per team.
Luca:
So we end up with more microservices and microfrontends at the end of the month when we started to have certain maturity that we had thousands of deployments per month across different layers.
Luca:
But that tells you how fast you can go, how safe you can be, and stuff like that.
Luca:
And did we screw up?
Luca:
Of course.
Luca:
Because naturally we have human beings in the mix.
Luca:
So sometimes you forget about a specific configuration.
Luca:
You forget to put behind the feature flags.
Luca:
You forget about these things.
Luca:
But that doesn't, nevertheless, doesn't mean that we screw up the proposal.
Luca:
It's just, OK, we found a blind spot.
Luca:
We need to understand how we can mitigate this blind spot that doesn't happen again.
Luca:
This is the mindset that, in my opinion, people should have more than, first thing is, OK, let's create a gate that basically is preventing people to deploy.
Luca:
And we hide behind this change advisory board that should know everything about everything that is happening inside the company.
Luca:
Usually even if you have the smartest people in the company, the cognitive load is finite.
Luca:
So they will never be able to tell you this specific service will not clash with the change on this other specific service.
Luca:
So you are basically creating friction that is a safe net for the management, not for developers.
Luca:
So let's invest more in automation and we create something that makes more sense for developers because those are the ones that need to speed up and be safe when they deploy.
Karol:
Right.
Karol:
Did you mean Accelerate?
Karol:
Accelerate, did you mean the book by Nicole Forrest-Grant, Jess Hubble, and Gene Keem?
Karol:
Yes.
Karol:
So if anybody would like to dig in, here's a QR code.
Luca:
of 200 companies worldwide where basically in the first part of the book they describe what are the traits of successful companies.
Luca:
And the second part, they describe how they tested or better, how they conducted the research for retrieving this information.
Luca:
What they discover is that there are some traits that make companies successful.
Luca:
One is how fast you can deploy, how fast you roll back if there is an issue, how fast it takes from ideation to production, and that basically is the base of the foundation of Dora Metrics.
Luca:
And that was one thing that nowadays in the industry is quite well known.
Luca:
And now there is a new book from Nicole called Frictionless that I think came out last month, I can't remember well.
Luca:
And it's basically moving to the next step.
Luca:
I didn't read it yet, but it's definitely my reading list.
Karol:
Okay, I don't see it.
Karol:
Otto Reilly would have to dig deeper to find it, but yeah.
Luca:
Let me see if I can find it.
Karol:
Okay, now if I just still took a look at the diagram we drafted on Miro, and I'm looking like, okay, so we have interoperability between the microfrontends being through the emitter, so we have even driven-like aspects that are avoiding the JavaScript problem of events and listeners.
Karol:
Then we have interoperability between the microfrontends and the backend, as in GraphQL or backend for frontend.
Karol:
And then basically, if we have that layer of a backend for frontend, whatever version that may be, then basically that is our abstraction layer that we then go into communicating with the rest of the ecosystem.
Karol:
So this is where my job begins, how to get that data moving between that particular backend of that frontend into the rest of the ecosystem.
Karol:
And this is pretty already standardised in comparison to what we have in microfrontends, where that, for me, is something that is very much abstract, because I don't do it simply.
Karol:
Of course.
Karol:
Because it's that abstract.
Karol:
It's just something that, as an architect, I do not really touch upon, and that's the interesting part here.
Karol:
So, okay, so that's...
Karol:
Any things that happen specifically if we talk about external communication as available from the internet?
Karol:
Because if we look at...
Karol:
Well, the frontend isn't available from the internet usually, right?
Karol:
If we have a product site or whatever, but then what is...
Luca:
You can share again the Miro board.
Luca:
I would like to show you one example.
Karol:
There we go.
Karol:
Back to the Miro board.
Karol:
Amazing.
Luca:
So, let me zoom in here.
Luca:
So, imagine that this one is your, I don't know, server-side rendering...
Luca:
Oh, sorry.
Luca:
Server-side rendering catalogue page, and you have classic example...
Luca:
Sorry, catalogue.
Luca:
And you have a classic example, an external advertising server.
Luca:
Let's do it this way.
Luca:
So, you have ADS server.
Karol:
In the meanwhile while drafting, I put the QR code for frictionless on the screen.
Karol:
So, if somebody's interested in looking into that, that's also there.
Luca:
So, in this case, for instance, I want to do server-side rendering of my catalogue, but the ADS server is an endpoint that they basically provide personalised advertising based on the user, and they show basically a specific element inside the page.
Luca:
So, that cannot be cached, has to be retrieved dynamically from advertising servers, etc.
Luca:
So, what you do usually is that this has to communicate with whatever system you have from mobile to whatever.
Luca:
So, you go with the common denominator, the HTML, basically.
Luca:
What you have here, sorry, when you are fetching this information from here to here, you are going to have back, let me reverse that, you're going to have back what is called an HTML fragment.
Luca:
Where is the text?
Luca:
That is nothing more than an HTML element that is self-contained, that contains all the graphics, text, whatever it is, based on a bunch of parameters.
Luca:
So, now at this stage is to a certain extent potentially malicious code.
Luca:
If I intercept that, it could happen wherever it happens.
Luca:
So, the tendency of what you do is sanitising this code and HTML.
Luca:
HTML usually is not malicious because they don't provide, let's say, a lot of JavaScript.
Luca:
There is probably a non-click thing if someone is clicking, is attributing that thing to the advertising or whatever it is, but it shouldn't be, let's say, too much logic.
Luca:
So, this one is usually sanitised, is injected inside the page that is rendered and shipped to the user.
Luca:
Now, the other approach that now is not there yet, but it will come very soon, I would say, is when you have an AI workload.
Luca:
Now, the AI workload, what it's going to generate is JavaScript.
Luca:
So, I have a chatbot,
Luca:
and imagine that at some point
Luca:
I want to do a trip to Florence,
Luca:
and instead of providing you
Luca:
a text-based approach,
Luca:
it's going to generate UI
Luca:
where you have a video of,
Luca:
let's say, what people were seeing
Luca:
in one place,
Luca:
and maybe they have,
Luca:
I don't know,
Luca:
some other ideas of what could,
Luca:
I don't know,
Luca:
a common itinerary
Luca:
or the most hotel
Luca:
from the people
Luca:
that are coming from your country,
Luca:
wherever it is, right?
Luca:
These are a basic example of microphone temps if you think about this, because instead of providing you contextual text that is explaining one thing, you can have instead graphic things that are generating in an encapsulated way with a set of elements and then pumped with data that God knows how they are generated, right?
Luca:
So, in a situation like that, now you have a bunch of full microphone temps potentially.
Luca:
Okay, we are in the realm of if, when, and it's going to happen, but you are going to have JavaScript here.
Luca:
There are already some examples that I've seen on mobile, for instance.
Luca:
It's very interesting, this approach, but imagine that you have like here JavaScript, a microphone temp JavaScript that is fully JavaScript.
Luca:
Now here it can be wherever, right?
Luca:
And it can be also that the implementation screwed up because it's using a specific version of a library that doesn't work.
Luca:
It has a bug, it has a security issue, wherever.
Luca:
So the idea here is, okay, how do we sanitise in a situation like that?
Luca:
And probably we're going to need something new or let's put this one here that sanitise this, that is a code sandbox that takes the code, parse it, run wherever scan you need to run in this code sandbox and then finally reaches the part that you need for communicating with your system.
Luca:
And that is becoming very interesting, right?
Luca:
Because now suddenly you can generate code on the fly, you can apply your UI and your design system because LLMs will enable us to do that.
Luca:
And now we have, although for security reason, you cannot trust whatever is coming because we know when we play with the system that the precision of the code is generated, is probabilistic.
Luca:
We are dealing with the probabilistic system is non-deterministic, therefore that you like it or not is going to screw up.
Luca:
So the code sandbox will become a sort of, if you want, a safe net for us to have this feedback loop that is communicating between the LLM and the agents to understand does it, let's say, work in the way that it is.
Luca:
But if you start to think about this, now you became to add a lot of security stuff here, a lot of logic and deterministic thing, security, style, et cetera, whatever it is.
Luca:
Now think how powerful it could be in transforming what today is a non-deterministic system that generates, rightly so, non-deterministic or probabilistic, let's say, responses because if you ask the same thing, it could provide the same answer or not.
Luca:
But now we start to add a bunch of layers of determinism in this probabilistic system.
Luca:
And what if we are not going to have the perfect deterministic system?
Luca:
There is no way that a probabilistic system can turn into a deterministic system unless you change the architecture or, let's say, mathematical implementation behind that.
Luca:
But in this case, we start to create, let's say, a safe net that will reduce drastically the way how we could screw up.
Luca:
And if you are
Luca:
in a situation like this
Luca:
where things are small enough,
Luca:
we are not asking to build
Luca:
an application,
Luca:
we are asking to design
Luca:
a thing with a certain constraint,
Luca:
then I think it will become
Luca:
quite likely
Luca:
that we are going to have
Luca:
something that is kind of interesting
Luca:
and could scale very nicely
Luca:
because with all the
Luca:
microservices approaches
Luca:
that we have learned overall,
Luca:
we start to have, like,
Luca:
I don't know,
Luca:
imagine a dashboard,
Luca:
one microfrontend
Luca:
that is generated from LLM
Luca:
that have a bunch of safe nets
Luca:
that will be served
Luca:
by a single endpoint
Luca:
that is integrated
Luca:
through microfrontend
Luca:
inside the same UI.
Luca:
Now the thing starts to become
Luca:
very, very cool
Luca:
because with this approach,
Luca:
you have a mix, potentially,
Luca:
of deterministic,
Luca:
non-deterministic systems
Luca:
or semi-deterministic systems,
Luca:
I don't know if there is a term
Luca:
in English to define that,
Luca:
that although you still control
Luca:
to a certain extent
Luca:
and it's just, let's say,
Luca:
being good on defining these,
Luca:
let's say, rules
Luca:
or deterministic nature
Luca:
for reducing or eliminating
Luca:
the possibility
Luca:
to have some outcomes
Luca:
that are not, let's say,
Luca:
I don't want to say correct
Luca:
because this is the wrong word,
Luca:
but as expected.
Karol:
And this is probably where a number of externalised APIs will come to play to be able to facilitate that.
Luca:
And the frameworks already have them because the React server component is nothing more than an endpoint where you basically render a chunk of the UI and is embedded inside a static part.
Luca:
So it started to become extremely interesting, this new world.
Luca:
This is an area of research that I'm currently looking into to see how far we can push these things.
Luca:
There are some missing parts, but we are getting there.
Karol:
Okay, that's probably going to be a very interesting feature and also touching upon interoperability to how to properly govern that and make those AI workloads hallucinate less and work to our advantage because working with non-deterministic systems is already a difficult aspect.
Karol:
That's only always.
Luca:
And I think this is...
Luca:
We need to take for what they are and not trying to make them doing something that they are not designed for.
Karol:
Or design specifically to train LLM models to be in a specific use case of micro front-ends and serving content.
Karol:
This is a different topic where we have training and then fine-tuning where training is towards working as a micro front-end and fine-tuning would be then training the model in the aspect of that business or that site or whatever the purpose is.
Karol:
That will be definitely an interesting avenue of research in the next years to how to properly make it a tangible use case.
Luca:
Completely.
Luca:
I think it's just that this idea itself could literally lead to a very interesting approach overall where it doesn't have to be let's say developed fully by developers but you need to create the governance around certain things that are developed as raw elements and then augmented through AI on the fly and then composed with all the distributed system nature that we have learned overall.
Luca:
Because now we are designing a UI and now generating certain type of code so there are a lot of nuances there and with all the checks that I was mentioning to making the output not harmful for the system it started to become a very interesting thing.
Luca:
So we need to understand how much we can push the boundaries.
Karol:
And let's leave it at pushing the boundaries.
Karol:
Hopefully, somebody will pick it up and try to push that boundary alongside you and others who are already doing this.
Karol:
And that's it.
Karol:
Luca, thank you so much for your time and for your explanation into interoperability of microfrontends.
Karol:
That's been enlightening.
Karol:
Now I know how they work at least.
Karol:
For me, as an integration architect it's easier to comprehend the nuances and I see analogues to my work just on a completely different level.
Karol:
Before we go offline this is the last stream we are doing this year but next year I already have a pipeline of loosely coupled till the end of February so there's some interesting talks coming up.
Karol:
First one on the docket is with Chris Simon.
Karol:
We're going to be talking about the living language.
Karol:
So we're going to be talking about how to maintain and how to work with a living language or a ubiquitous language from domain-driven design how to make it maintainable and how to keep using it without sprawl and deviations that would be harmful to our organisations.
Karol:
I think this is going to be quite a challenging and interesting conversation to be had.
Karol:
And that's on the 14th of January so we're taking a little bit of a break over the holidays and New Year to reset and do some other things than live streaming here.
Karol:
And that said, again Luca, thank you for your time.
Karol:
Thank you for joining us in this lovely last session of the year.
Karol:
Happy holidays.
Luca:
Happy holidays to everyone that is listening to us and they are listening also to the recording.
Luca:
So happy holidays to you and your family.
Luca:
I hope that you have a good one and a relaxing one.
Luca:
So yeah, thank you again for having me.
Karol:
It's been wonderful to have you and everybody happy holidays and happy New Year.
Karol:
See you next year.