 Hello, everyone. I'm Rahul Gaur. Today I'll be talking about breaking down the last monolith and I work as UI UX platform lead at innovation. So we'll be discussing how we can take the micro services strategy and apply it on the front end. So the agenda of my talk today is what are micro services in a very brief and what are micro front ends and then our front end story. And what are some common integration strategies that are out there. And how we deliver value after incorporating this solution into our platform and you can also leverage that. And what are some existing open source solutions out there that worth looking into. So what is micro services? So in order to put it in a more simplistic term, I would like to describe micro services as a development technique that allow us to do independent deployment of different parts of system without hampering or harming other parts of the system. So now in order to understand how micro services came into picture, we need to take a look back the whole evolution of software in general. So in the beginning, we had this monolithic system which would serve everything basically started from an installed system on your desktop moving to web where you would have a single monolithic application which would have its own UI persistence layer and everything. The problem was as with the constant onslaught of requirements and features and everything, it becomes difficult and hard to maintain. And so we came out with a new development technique that we today know as our classic front end and back end kind of approach. Where you would have this backend server, which would deal with all of your database related stuff, business logic part. And then you would have a UI application, let's say in case of a single page application, which would consume these resources through rest API and develop the UI. So what this approach provided us was ability to have different team work on different part of systems having their own roadmap and having bit more freedom around where they can structure their application in general. And as with the advent rise of internet and cloud technology in general, the cost of hosting services on internet became so dirt cheap that we took the same old principle of solid design and single responsibility purpose and taking that, breaking that backend monolith into micro services and developing small services that were targeted to do one specific thing that offered us flexibility to choose the technology stack of the service as per the requirement or the use case of the problem that we were dealing with. So it really eased out a lot of development issues, coordination issues and really help to scale and build large platforms. But what about front end? Front end in most cases was still single page monolithic web application spanning across multiple micro services. So what happens in general is in a backend architect's mind UI tends to have a very low or small impact area. So what we really focus on services matter most and we have to design our services in such a way that they can be deployed and maintained and by, you know, two PISA rules, teams can roll out new services and etc. So this is the how the general notion is. But wait, what are microservices have actual human users? So what happens in real world is front end has way more huge impact area than anticipated in general. You have this green thing here. Now, in that, like you can see their different UI components are collected together as they depend on different micro services. And now what happens is on the backend platform, each of these services can be worked upon independently. You can redeploy a service with a quick small change. But what about the front end part? There are too many complexities involved there. It has to, you know, you have to UI has UI is very valuable because it is the final point where your end users, your customers interact with your product. It is more differentiate your product from your competitors. So what happens with UI now for any small change anything, the whole front end has to be rebuilt and that has dependency across different components. And how do you basically, you know, how do we fix this and the micro front ends? So what are micro front ends in order to put it in a simplistic term? The whole idea is to take this one large scary thing and break it down into more smaller, maintainable and manageable pieces. You know, and then being very explicit about the dependencies between these independent components or pieces that we are trying to build here. Now, what does this allows us to do is we can, you know, take our own technological choices, our code bases, our teams and our release process. Everything is able to evolve, you know, independently without excessive coordination. So how do we like, how do we structure the whole front end into a more understandable and manageable, you know, state? What we are trying to do is we want to simplify the whole front end, this whole service oriented architecture. And what we are looking for is a true vertical decomposition where each of your micro services have their own UI, which can plug into your front end platform and deliver that experience. And which should be maintainable and manageable by, you know, single team as we do on the back end for the micro services in general. So with this notion, I would like to describe a bit about the front end story and why and how we pick this whole strategy. So innovation started developing its healthcare platform in 2015. At that time, company had a lot of people who were well versed with AngularJS, Angular 1.x basically. So that was our technology choice back then. And so we started developing Angular 1.x application, a brief background about me. I have actually from 2014 to 2015, I was part of a wave that rewrote so many jQuery, Jinja, Backbone, Portals into Angular 1.x. I did Angular 1.x web application that was first in I think 2013 as a part of my Google Summer of Code project. That was the first time I ever wrote JavaScript. I was mostly Python and C kind of a person. So coming from there and like, you know, the whole idea of building a product is picking the technology that works best for you. So we ended up building AngularJS's healthcare platform. We had a very aggressive go to market strategy. And in order to gain substantial, you know, market share in already very competitive healthcare market, which was dominated by very huge players. We were working full pace, rolling out features after features and gaining substantial ground in market. And healthcare is one of the very difficult domains to develop applications for because there are a lot of cross cutting concerns that you need to take care of. So this was how our whole system looked like back then. And in 2016, 2017, and we decided that the kind of scale that where we are going this stock and this kind of architecture is not really going to cut it. So we set down that we want to come up with a better strategy to break this down. And as the product grew, basically, it become this large and manageable monolith and you do one change here. It will impact something somewhere else and platform. Some, some user gets pissed off and, you know, it was very painful. And there's, there are a lot of, you know, if our UI or a platform goes down, there is a care coordinator monitoring, you know, coordinating with a particular patient. They cannot do that. And that was really very critical because that patient needs certain monitoring at certain time, which if we miss, we lose the whole purpose. So what we decided to do was we cut our monolithic whole model into, you know, it's along, along these very core domain, the specific domain that particular application was targeting end to end. And wrap that whole thing into a self replaceable web application, which had its own UI, the blue layer green part is one or more micro services for that particular product vertical and their own persistence layer database, whatever they want to choose. And so with this, we were able to model our teams along, you know, around the particular healthcare solution that that team was targeting and providing them complete individual stack. Basically, which they can plug into our existing ecosystem and, you know, leverage all the existing integration features. If you, if one product wanted to interact with another product, all that coupling is done on the UI layer, no two services or pillars are coupled on the services layer. So that allowed us to have more easily maintainable, manageable and deployable systems. So, so let's talk about what are some common integration strategies that can help us to achieve this kind of, you know, architecture and what we did at innovation. See, so our core core idea, the whole cost of shipping any new feature in our product becomes so expensive that we were moving and innovating at a very slow pace. And we did not want to break anything by doing some new, pushing some new radical feature into production or any that kind of stuff. So we wanted to reduce the time it takes to roll out new features. And to do that, we came up with these metrics to base the whole approach on out of this team ownership develop independently run independently were pretty much critical to us. Being technology agnostic learning from our whole microservices and backend platform was also something we wanted to have for the front end stack and ability to fast load the application was also very critical native support and sharing basics between these front end application, having a more modular application, corporate identity across all of these product verticals and smooth user interaction. This was one of the critical pain point and also the differentiating factor for our product where we were completing there. Usually it is dominated by large companies and they have solutions like we do, but those solutions are either acquired by some other company or third party. So the end user of the product, they have to have like 50 bookmarks on the machine. And at any given day, they would have to click on 10 different links to go to different context of application to just to get by their regular job of, you know, monitoring the patient health and providing doing the necessary paperwork and all of that stuff. So when we gave our Angular 1.x application to this user, it offered the smooth user interaction, single page application, user experience, and that was really a game changer for us. Before that nobody was doing single window kind of a shopping experience in this domain. So to do that, one of the basic strategy to do this kind of approach is have each of your single page application or, you know, running on a different servers and routing them through a nginx based routing or something. But as you can see through the cases, some of the critical part that we were targeting did not really were not being accomplished by this approach. There is another good approach, server side include, which is also very powerful, but it is basically you can think of it as an iframe on your server. So I have this EGS template and I can have outside include colon some URL and before rendering this HTML, my server would first prefetch the whole HTML fragment from that URL embedded in the whole HTML markup and then render my EGS template and give it to the user. It was good too. It did help to tackle a lot of cases, but we were not able to get the smooth user interaction that we were looking for. It was not fast loading. It was not natively supported because you need to have these ESI preprocessors. This was concept popularized by Varnish, I think. So next approach is code level integration where each of your components or pages could be a standalone NPM package. You can publish them and then have a final react base, which would require all of these components and basically build the whole thing. You can do lazy loading as well, but most of the cases were being met, but we were still not able to run independently and we were still not technology agnostic. Coming from our learning of Angular 1.x, we did not want to invest in single framework for our stack. So what else could be done? It is application shell architecture. So application shell is a minimal amount of HTML, CSS and JavaScript that is required to, you know, power up the user interface. The application provides ability to load fast. It can be application shell can be cached and it has ability to dynamically populate content in the designated area. So this looked like a promising approach after a POC we figured out there are certain challenges, but still best shot we have. So application shell basically provides a single page application kind of routing experience. So we could basically navigate register the routes for each of those single page application on some other URL and have the CDN bundles on some other URL and have the top level routing of each of those single page application registered on application shell. So whenever you click on a particular link, the application shell will fetch the manifest which will have all the information about the CDN path, JS bundles, CSS, etc. And application shell has very lightweight minimal logic just to take all of those meta information and initialize the single page app in the designated area. So this looked like a very promising approach to us and a single page application provides different kind of integration option. You could do build time integration. You could have a runtime integration via iFrames or web components or even JavaScript function based APIs. So in order to take this thing into production, we developed something at Innovator which we internally called UI Engine. So UI Engine is a very simple declarative dependency injection framework used for application composition. It provides ability to do, you know, it maintains the application lifecycle and it also provides us this whole application shell architecture for the front end and ability to do, you know, plug in your micro front end apps. And it has support for both on browser and on server side. So a bit background information of about UI Engine. UI Engine was developed in 2016. At that time I was working a lot with NodeJS. Once I moved from Python to NodeJS, basically it was my de facto stack for developing full stack applications and products. But the problem with NodeJS that I constantly faced was NodeJS had a lot of good libraries, but nothing really was solving the problem of architecture. So after learning a bit about spring and dependency injection in version of control, at that time I just basically came up with this express-based layer which would allow me to do dependency injection and allow me to do have more structured and robust NodeJS applications. So when we were deciding to move to this new stack, that whole code base, that whole site project came into good use. So a bit information about application shell architecture, the UI Engine renders this application shell and it basically requires these four major components. We have a PWA manager which basically maintains and monitors the lifecycle of each of the micro-app registered in our stack. UI Engine has a store which is very much similar to something like Redux, but very lightweight, just there for top-level communication between different micro-application. Then we have a loader which is event-based and its work is to basically fetch the manifest of a micro-app and define its scope and routing in the application shell. And what really couples any single-page application in general is the router. After you end up using Angular Router or React Router, you have different React components, but in order to navigate between them, you end up using their own router and it couples your whole stack into that particular ecosystem. So we use Universal Router. It is an open-source project, very small and lightweight for routing between different applications. So all of these things basically provided us with the ability and more flexible architecture. If you can take a look at this architecture, it is a very simple but yet very powerful architecture. UI Engine is an express server which runs as a registry app server and different micro-apps can run in different UI Engine instances. And once they basically they register themselves to this central registry server. So basically any Vizgi server that can serve our valid manifest JSON file can register its UI, abide by our authentication policy. So they can register their UI into a framework ecosystem. So how each micro-app server works is each micro-app server is nothing but an express middleware which serves the your static content or you want to have your express-based route, all of those parts, and it has the initialization hook. So as soon as your micro-app server comes into an existence, it registers its manifest to UI Engine's registry server. And on the registry server, as soon as we receive the manifest, we do certain processing to standardize and scoping the parts and HTML and all that part. And we maintain a clean links for those applications. And now whenever user access any particular application, basically we could just serve that manifest and UI Engine shell will take care of spawning the whole application into existence. Each UI Engine micro-app has an architecture like this which has an app.js express-based hook to register it in a web server. Then it has a server part where each of these teams can define their routes and basically other server related stuff, sockets and all that part. And then you have your UI part, you have your own bundler, and you can work on your part of the content of the whole total web application. So how does UI Engine basically is able to maintain the lifecycle of different applications using React with Angular or anything that you want to use. So we use this third party, basically this open source project, single spa, basically it is a very good and easy to use place if you are looking to explore into more in micro front end. So UI Engine uses single spa, it abstracts it. And single spa's responsibility here is single spa provides the ability to mount and bootstrap any single page application component into an existence. So UI Engine abstract a lot of interfacing between single spa and give us a more cleaner interface. With single spa you are able to even run multiple UI components on the same page, basically. We are not doing this right now. We do not want it to have too many different framework libraries run time into in our production environment. What we are rather doing is we are using single spa to mount and maintain the lifecycle of a complete single page application of a particular product vertical. So monolith is not really a bad design choice but you know what microservices constrain us to do. So basically that if you are building a monolith and you follow the best practices and everything, you will have a very well-maintainable and manageable application. But microservices constrain us to do those things like which were optional while creating a monolith. So there was a use case that in certain scenarios we did not have that kind of infrastructure or scale where we could deploy micro front end kind of architecture in that point in that kind of a scenario. All of our micro front ends can be installed in a single express base and run as a monolithic application server as well to cater some of our on premise deployments that we do. So there are some challenges like if I will talk about if I would like to address one of the major challenges that I faced throughout and our team face was with styling. So over the years many approach has been taken to write maintainable and make CSS a bit more manageable. But still CSS is a bit difficult you know especially if you have a lot of teams working on your product. In that scenario let's say let's take a scenario like and especially when you are talking about micro front end. A lot of these existing problems with CSS are actually escalated and difficult to mitigate at times if you don't have a proper strategy thought through. Let's say you have two different micro apps running on a particular page. Each of them include a style sheet both have like this property h2 color black other has h2 color blue somebody is going to be disappointed. So these kind of challenges can be taken care of you follow a proper BEM base naming convention or basically you know some other approach like CSS and JS to scope the styling of your component. So we were not facing this problem very specifically because a lot of our application as I said are complete single page application. We are not injecting multiple component made by different team on a same page. Whenever user clicks on a tab there is a one single page application maintained and managed and to end by a particular team. So in our case we have a shared component library on react which all of these teams used to build their you know you guys are toolkit to build their UIs and everything. So and also we follow SAS for a lot of top level teaming and scoping to mitigate a lot of these issues. Another issue is how do you maintain and monitor so many micro applications where do you deploy them and even if you are taking approach of containerization doing it on bear EC2 machine. Not really advisable if you have a proper infrastructure and serve you know like ECS service or something in place which you can leverage then it can be a bit more manageable. Or even if you can you know go with a serverless approach for each of these micro applications then it is a bit easy to manage lot of these mitigate a lot of these challenges. So after moving our whole application to this micro front end architecture how we were able to be benefited by those things. First improvement was the load time. The load time of our application came down to seven seconds from the monolithic angular application to when once we moved to UI engine. The total payload basically which was required to power the whole application shell architecture was something around 220 kb. These are Anjizip numbers. So this was a significant improvement. Our light basically this core was around 2023 in our existing application. Once we moved to this new architecture this whole score drastically improved for us. This was one of the major outcome. Another thing is process. As I told earlier we wanted to be able to do independent deployments basically different deploy a chain different parts of system without impacting other parts. So we were able to come up with a very clean and simple pipeline for each of those teams. They will commit their code and basically we'll have a CI pipeline which would run all the testing suit and everything. Once done it will basically it is hooked to npm version whole to publishing the whole scripting tool on the CI which would publish the similar compatible version of your application to npm registry. And after that trigger the Docker build Docker has access to the npm registry. It will basically fetch all of those whatever is required for your application and build the Docker is image of your micro front end. And basically we have a Jenkins hook so it gets deployed automatically in cases on premise deployment infrastructure team has to manually deploy those at those deployment. So I'll demonstrate it through a small video like how this whole platform works in production. So this is our registry server which has just login page right now and it works properly well everything. And next part we are going to spawn basically another Docker is image as soon as it comes into an existence that gets deployed in our infrastructure. You have this new micro app registered in our cluster and ready for our users to use the outreach team can basically you know do deploy and add features as they want and have their application available there without impacting any other part of the system in general. Likewise you can add any number of application. Now with this there is another new challenge initially we never thought of this challenge every link that is there when you click on it you will get the page but what if one of your servers are down. So the UI engine also you know establishes a heartbeat whenever application register itself in our cluster we are constantly monitoring that application. If the if you may miss certain amount of beat will disable that application and make it unreachable. Basically unaccessible until it is available again that application so UI engine will sing the state and refresh the UI. So this is a bit of a scenario that we basically we anticipated and like these are something that you might also need to think through proper. Lee before moving into this kind of architecture so another major improvement of win for us was incremental upgrades. So the whole idea is that you know having the ability to rewrite parts of our application without actually you know come doing a complete tear down which was not previously possible. But if you can see here this is the Angular 1.x application and this is a very complex healthcare definition tool which was which was very performance intensive and it was adding a lot of load on the DOM. So what we did instead of rewriting the complete Angular 1.x application we were able to rewrite that query builder part in sweat and as you can see the improvement between the two UIs is drastic. So another major problem that monolithic application architectures offer is onboarding new people. It became really difficult for us to hire new talent because Angular 1.x was not really something you know you can find basically either you need to have very deep understanding of JavaScript and Angular 1 in order to write performance application on Angular 1.x and even if we get new people who had certain experience were difficult to onboard them. The whole micro front end approach really offered us a very easy and you know efficient way of onboarding new people. We can basically anybody who joins the team all they have to do is build one micro front end app and they get the whole idea about how the whole platform and the ecosystem that we have it works and they are able to use some of the technologies that they are more comfortable with and they are more proficient with and use that to deliver value in the production environment. So to showcase that I had a intern who joined me a month back after like getting onboarded onto our stack he was able to he was like you know he did not want to write too much HTML CSS to build pages. So he ended up building a page builder that would allow us to utilize our existing component suite and stitch these components together and publish a page. So these kind of innovations were which were not previously possible now became a common scenario in each of those teams. So basically in order to summarize the whole whole talk as the front end continues to grow and get more complex over the time there is a growing need for more scalable architecture in general. So we need to be able to draw you know a clear boundaries and establish right level of basically established right level of cohesion and coupling between different domain entities. So we should be able to which will allow us to be able to deliver and you know reliable and scalable software at fast pace and also have autonomous teams. So while far from the only approach I think that we have been able to very much successfully apply this micro front end architecture approach on our front end and basically reap lot of benefit from this. I can only hope that these kind of strategies will become a de facto way of developing large web applications coming down the line in future. So if you are interested in learning more about micro front ends. I think singles power would be a very good place to get started with because with this you will be able to even apply the whole micro front end strategy on your existing application without doing complete tear down. Only problem with single spies. It does not allow independent like you know CDN kind of a deployment. All of these cold have to be bundled through a single source file. So you are engine help us to basically isolate a lot of those complexities. But it is a very good place to start with. If you are looking for something more like a UI engine kind of approach open component is a good approach. I think it also leverages a server less mechanism. And if you are building a front end application in front end platform in today's time you should definitely take a look at open components before making any further choices. I would say I have recently also written a blog post about this whole micro front end approach on dev.to which has a lot of resources that basically helped us over the last two years. So if you are looking to learn more about this do check that blog link. You can it will really save you a lot of time if you want to explore more about this strategy. So I think that is all from now. I can I'm open for questions. Hello. Since we are you also using the micro services kind of architecture but how you maintain the different versions because currently we have different different microservices with the different different versions. And that is the beauty of microservices like you have your own CICD of your microservices. Right. Yeah. So how since your microservices are tightly tightly coupled with your front end how you manage to do the different versions of your microservices pushed into your production and it will not affect your front ends. So so micro services like it depends on the kind of use case that you are targeting all microservices don't need UI some of the domain you know very low level domain logic kind of stuff. Let's say something around our ETL processing and a lot of those data processing services. They are still standalone services which can be behind the stack. And more of the app you know regarding if you have a particular micro services that cat has to a particular UI. So if you want to maintain two different versions of this micro services and have the same version of UI handling this. It's something your UI then needs to be like this. These services should be backward compatible. You have bumped your service micro service to a particular level. Change some kind of a model. But if UI is not incorporating that then again it becomes a problem for you. But in case the services like backward compatible you can have these two services running. And if you want to serve both of these basic single have a single UI serve any through any of those services you will have to define something on the UI front to like pick with service. So we have such scenario in one of our application where we built a new patient service and we had the existing patient service service and we had a new UI in react and it needs to support both. So we did incorporated certain mechanisms through configuration when defining that micro application you could configure which version of service this UI will use for that part. Each of our UI application basically application is a express application express middle where it will have its own server part as well on that's express layer. We handle proxies like this or if you know we have multiple micro services downstream we can compose the data response back and forth front end kind of approach that is also possible. I think that is something which will be required you will have if you have a complete web server and through that you can basically manage which micro service you want to use that will also allow you to get that kind of benefit. Does that answers your question. Yeah mostly here. Okay. Thank you. Hey hi when you have multiple components in your micro front end architecture how do you manage the state of the application when each individual micro service is managing its own state how the whole application manages different states of the application. So we have this top levels store basically on in the application shell itself which was inspired by Redux only so each micro application can subscribe to that store and dispatch actions to that store. So if you have different micro applications in the platform if one micro application does something which needs to impact something else will update the store and that other application when it comes into existence. It can basically utilize that state data and reflect that on the for the user end. Is that something for instance if you have two micro services available at that particular moment and it has two states different states which they are managing. So how do you solve this problem. You're saying you have a global state management and when a a particular micro services come it comes into picture you. So in our case like what was our whole scenario if what you are talking about if I have a page and let's say there are five component each of these components are powered by different micro services. Right in those kind of scenario it is very tricky. First of all you have also complex the whole UI you are putting a lot of different components and composing that it offer. It is a hundred percent vertical decomposition where each element on your page is powered by a separate service that has a lot of you know complexities which I am yet to basically learn and find out what we achieved in our platform was we did not take that take that route what we did we split each of those application like each single page application is backed by a particular service for in our case. So if you switch a tab then the second micro application comes into picture and it basically works on its own its own service layer basically. Okay okay thank you.