MICROSERVICE WEBSITES

MICROSERVICE WEBSITES

July 12, 2019 12 By Bernardo Ryan



so I'm going to talk about market service websites so in the beginning of last year we I started to work quite early in the face with a concept for a new mobile first website for IKEA and during the summer last year we released the first like MVP you might say a static blog a key M to the static site blog and then this summer we have released IKEA M to Norway which is a pilot of a mobile first full full IKEA site so this site consists of five different services or applications and this is going to be my example in this talk today how how we use these concepts to basically do a mash-up between these five different five different services and applications so that end user only feels that there's there's one one site and not five different just to be clear we also have made some partial loss in other markets so we have two or three services running there as well so it's not only Norway and right now we're working on some desktop better desktop web support for for these kinds of devices browsers so first of all if we go back why did why did the project even why was it created in the first place so one thing was that the old web site had some performance problems so that was the first thing that we burned to address that really really great web performance for especially for mobile devices and but after that we realized that we wanted to find an approach that made could make a scale in terms of horizontal scaling and development wise so we can have more many teams working on different parts of the of the web and to be able to deploy autonomously scalable development and then lastly we also we also realized that we didn't want to make another rewrite like five or seven years ten years from now we wanted to have an evolvable system so that we can take parts piece by piece and lift them to something new and better and so we don't have to make this whole transaction of making from one web to another kind of web and this is going to be the structure of my talk today so these three things three different parts may also be seen as design constraints and this Venn Benesch diagram here these are design constraints and we want to find solution in the middle here and just to be clear this this might not be your design constraints in your organization source or our companies but I think that if you have an external website performance is is quite important and if you want to build web websites with more than one team you need you need would be curious about what I have to say as well but if you only have one web leaf ultimate team your life is going to be so much easier so it's a code it's of course a trade off and this does just only apply if you have more than one team and also maybe you don't want to have an evolvable solution maybe if the it's going to be evaluated like five years from now if if the business case is still valid then you can make it rewrite so just want to be here about that so let's again very briefly about performance and this is not a web performance talk but I want to have this as a base the performance is quite easy when you start building websites because basically hello world is the most performant webpage and then it basically decorates from that from there so you want to have this is a base and make sure that we don't degrade performance as we go and develop the architecture so there's a nice very nice report from Miss West uh which is part of Akamai now with where these graphs are shown and they show conversion rate how the how the conversion rate is affected by end-user performance and page load time so here we see that if you disregard the first two seconds which is basically four fours and 500 HTTP status codes you see that the conversion rates start to drop off to two seconds so you have you have up to two seconds of page load time before something bad happens and this is both on desktop mobile and tablets and all kinds of devices but it could be different behaviors so for for IKEA the whole IKEA calm web has over two billion visits last year so the conversion rate is quite important for for a key as a whole so we really want to have good performance done and be below this – second – second limit so there's a nice oh sorry so our strategy just very simplified has been to as much as possible when applicable have as a simple server-side render HTML pages as possible and then for other use cases to do something else but that's our like base we want to make something as simple as possible and of course that's sometimes hard but yeah with with some solutions to other problems we also use HTTP – which makes things in idioms impure simpler we don't need to bundle a lot of stuff that you have to do with they should be one so this approach has given us great page load performance and then you might wonder how but how great is it really there's a story here that the Norwegian web manager Nina went to an external conference and there the the manager for Google Norway had representation about how to survive digitization era and web performance and they have made some surveys and performance tests on the major sites in the Norway and according to him the story was quite sad because there was no site in Norway that had a patient load time below 1 second except one and that was the IKEA m2 norway site that we had released just earlier a few months before so that's a great success story and great approval that we have we have good performance in our in our solution but moving on to the topic of this talk market service web sites and the scalable development again we want to make sure that we don't degrade performance when we add things and complexity so if we move up an abstraction ladder we there is a concept of to pizza team to pizza team rule from Amazon that I think Jeff basis has coined the CEO that team should not be larger than they could be fed by two American pizzas which is for me at least around 10 people so so fairly large family pizzas depends on I Marcia eat of course it's nice constraint that maybe you could get away with 12 people of 13 people but you're hungry so you need to find a way out of that situation so how many of you know Conway's law out quite a few so simplified if we want to have these teams these team sizes of like ten people or so following Conway's law we need to have services that are small enough for one of these teams to handle so we want to have use this isomorphism of Conway's law and I'd like one service per team and maybe one team can have more services but this should be at least bigger this granular and not more not larger services than this so in our case we have these five different services for ikm to Norway it's a simplified picture but it's good enough for example so we have these teams they make software and they want to deploy autonomously and be independent of each other but the usual way would be to integrate these teams in a common front and the front end application which is a problem because these teams can't get out get their software out the door because they're they're being stuffed by the by the fronton team and the backlog just keeps growing and growing it's very tempting to add just more people to the project and three product and then you have this bad a feedback loop of adding more code more people more bugs nothing can be done a diminishing return and a bad bad final state so one what we want to have is to have these have the front and being part of these services as well so that each service on their own front and from from as much as possible so that they are self organized they can develop release and test themselves operationally responsible and they own the whole lifecycle of the services they create and for example for for our product products team here they are integrating further down below the stack of course there are some product database which are have a number of years have lived quite a few years but as much as possible aiming for this picture so it doesn't stop there because we want we want to find a way for these to collaborate with content because now they are independent websites basically and we want we want to be able to share the content between the services so that for example the menu is shown on every page and we have these fragments here for products for example on the search page but also on the like more inspirational content below the picture here so we have titles and prices and some campaigns and these these this information we want to be updated as as fast as possible so we really really want to reuse the contents in some form of components so for us we have we are relying heavily on a concept called transfusion which was coined by Ted Nelson in the book literal missions in 1980 and the concept is very simple and here you're using it every day today when you're browsing the web so you have this large document like a web page and it's having a reference to my smaller document the fragment may be JavaScript files it says file an image and the browser in terms of client side transfusion is making it seem like this is one document and is kind of including the fragment into the into the consuming document itself so the the only difference with between what what you would usually use in browsers and what we are using in the IKEA m2 project is that we transclude HTML from the fragments to the web page and there's two different ways that you can transclude you can transcode on the client side like like you normally do and also on the server side which i'm going to talk a bit about in a few slides but just to be clear this concept here allows us to cross the service and team boundary so that pages from one service and team can access fragments from another server some team and so this allows us to collaborate between services and building this kind of mash-up between different web pages so si-h that includes is a service side transfusion technique technology it was a standard proposal in 2001 so it's a fairly stable fairly stable spec even if it's not a formal standard w3c standard it's implemented in various idioms like Akamai and fastly and has nginx and Apache plug-in support and also there's quite a few libraries that you allows you to add at a site to your web service for example no DSi as NPM package and it works like this that when the end end user makes a request its hitch hits some form of edge web server if it's on a CDN if it's on your your web servers or something in between doesn't really matter but like the outmost web server before their requests hits the end user so then Lisa makes requests to ash web server and it's fetching from the origin and the origin document contains a nice I include tag on the way back the edge web server TSI implementation parses document and sees these assign to tags and makes HTTP requests to the source attribute in the include tag and when those HTTP requests are resolved we replace the ESI include tag with the contents of the fragment and return the page to the end user and the end user and user has no idea that the resulting document was actually being have several parts and there was some some kind of collaboration between the scenes here so it's totally opaque it might be good to remember though that this is a bit of a costly operation because you need to parse every document that goes through this pipe so you might want to cache this for for some time we cache it in 15 minutes which is good for our use cases and let's just shake yeah and before I move on I want to say this that I think that edge site includes is the most underrated web technology today and you should really have a look at it and this this phrase is so important that are going to say it once again ESI is one of the most underrated web technologies out there today and you should really have a look at it okay so now hopefully you remember something from my talk so if we moved it to the client side you can do basically the same thing with Ajax so I made an web component custom element to porch of Marc Nottingham's ashing to the dirtiest and it's worked a similar way as sigh so the browser now sees an Asian clue tag and it's making a just requests to the URL in the source attribute and it's replacing the the contents of the ejector Ajax responses replacing the innerhtml with the contents of responses but this is just an example it's fairly easy to just make some a just requests and replace some inner HTML with responses and there exists other similar libraries to this and I want to be clear that the IKEA empty part is not using this in production but I think it's nice because it makes you shift between ESI and a she clued very very very easy alright so when should you use ESI and when she did use Ajax I'm a consultant so it depends of course but what does it depend on well I think that since it's nice that we do a lot of stuff behind the scenes and also to as much as possible support non JavaScript browsers and get get great performance it should use ESI as a base technology for doing translation but then you could use Ajax you you should use a jamais Constitution for personalized content city wants to want to cache the results also to use its Ajax transition when you have for example have client-side rendered page just like single page applications and maybe just JavaScript components because you're no longer on the server side when you're rendering under in the client side of course and maybe do some lazy loading for content below the fold so you don't put so much pressure on the web server and also make the patient load time seem better so yeah so this has allowed us to share content between between the different services the menu the different product fragments and another screenshot here on the right the front page but we're not done here what about styling because now we can transclude HTML between different services but just HTML enough won't cut it because it will not look great if you say the least so here you have basically three different options you could just look at HTML as a consumer and they just reimplemented a CSS according to some style guide or you could agree on some form of implementation of a common CSS framework like bootstrap but for for our solution and you could also find a way to export CSS and optionally JavaScript from the fragment producers producers so that it's possible to import by the fragment consumers and the two first options I think creates a high amount of coupling the more coupling the more teams the more coupling you have and the third option is what we want to have here because that gives us a high cohesion because the HTML and CSS has been crafted by the same team so a first approach here would just be for a consuming team to just have a static reference to a CSS and maybe a javascript file but since we want to have an very very long cache time for CSS and JavaScript files because it's a good practice and we get good performance as well we use this cache busting – post hashes in the name and this becomes a problem because if we want to update this as a CSS file the name name change so we make basically to mail every email every consumer of that file saying well yeah here's the new version maybe point the reference to that instead so we can deploy we have this deployment of the CSS file everywhere so we need some form of and that's not too really good so we need some formal inversion here and we're in m2 we are using ESI as this inversion layer so instead of the webpage referring to CSS file directly it's doing si transclusion to a file that we call a fragment resource a research fragment that is referring to a specific cache bastard CSS file or JavaScript so that the fragment consumers never know about a specific version of a file so it might also be good to know that we're now not talking about fragment instances but rather about fragment types because you don't want to include one CSS file for every fragment instance that you consume only the fragment type so we have some form of type type notion here I don't want go into anything more in detail but that's it so these two concepts of translation and research fragments has allowed us to to have these five different teams and services and deploy the deploy these autonomously and have high high degree of Independence between the teams so we are doing one or two releases per week per team which is not continuous delivery but it's quite good and did the different team can adapt and release more aggressively if they want or it depends on their on their domain on their problem and as a system as a whole we have around five to eight prussians releases per per week which if you would translate this to the old way of them of the monolith would be a really really huge number maybe for a similar thing there's a lot of coordination costs of all with not not having this division of different services are you done are you done we're done yeah we're not done you know you know the drill so this allows us to have really a lot of releases and to have a fast pace and it seems to be independent of each other so moving on to well of ability because even if we even if it were nice state right now the world changes we don't know about the future we know that client-side libraries tend to evolve and change every zones of years and we want to make sure as much as possible to some some kind of extent that we're able to evolve the solution over time so we don't make need to make this big rewrite in the future and now I'm going to go a little on the side and talk about briefly about alternative art architectures for components so there's a tag on Twitter called micro phantoms which I believe that this micro service websites architecture is part of this style of developing us at least composable us on the web so and if you look at the links on that twitter hashtag you see two different approaches basically so either you say we standardize on one-on-one library maybe react or something else and let all our components be our all shareable components we've written in react or we can have this diversity of different frameworks and libraries on the client side so I'm going to go through both of these but start with the second one so with this style I think we have a really bad performance problem if we follow this ID and if we if we value performance because if people if web developers have a problem today with getting good performance out of one framework a library client-side library and also using kind of an isomorphic approach maybe if they're advanced it's going to be quite hard to load this different client-side libraries to download them parse them evaluate them and not having a degraded performance compared to having one library or maybe having enough no library at all so I think that a client-side diversity in terms of frameworks and libraries are not very very good in within the same page the web web is a fantastic diverse place but just within a single page we don't value diversity we shouldn't value diversity because it becomes becomes a performance problem so but just to conclude here the glue here between this components is is the web components custom elements which i think is a really nice technology but just having having multiple libraries on the same page it's not a good thing for performance so if you then take the opposite opposite approach say that we standardize on one library react just being an example and saying that every team should use react we use we are writing our all our components in react and sharing them between the teams I think this is a scalable overtime problem and maybe it's more obvious if you look at this this way and we have this five different different services and sometime in the future we might say that we want to move to another library and inevitably that will probably be the case some number of years from now inhabit hypothetical case so how should we do this move from react to maybe view without hitting this problem of having this combination of libraries and frameworks which we know is a performance problem I think it probably can be done by some basic abstracting away both of these libraries which is a kind of costly development operations to do and basically doing a rewrite but just in another way and rewrites is it's something that I have a quite big problem with because the business doesn't get anything out of it it basically it just solves a technology problem so if we can avoid this we really want to we really should I think and that this doesn't mean that that reactor view or any library is bad yes that having this using them as a glue for integrating between different services in a micro Service website or front-end is a bad idea I think so what did we do well we're using transclusion but we need to submit to find a way what to to know what common dependencies can a fragment can fragment producers assume that's our way of framing the problem of how to how to write components because we know we need CSS for components but some components might also need JavaScript and we need to figure out how to write a Java Script so and just rephrase this if Emily if if I'm a little fragment and I'm going to the if I go into the web page what what is what doesn't my environment look like what can I assume being there in terms of capabilities and in order to scale over time for us we think that just having a CSS reset a basic set of polyfills that we agree upon and then having very basic typography like the font and maybe some header sizes allows us to have this architecture so shared fragments have no dependencies and we have these five different services which are written in a bit different ways so our editorial content and the product pages are just being static files on the CDN so we we have uploaded over two million files to the CDN today and it that's also a bit of part of the great performance at m2 has on the product page we are using a tiny amount of prayer code for some interactive use cases and the first version of search was also written in pre-act now we have expanded on the under search search service and a dedicated team for that and it's being helps has been were written in vue.js and was actually released in austria yesterday and so we allow ourselves to have these different different technologies depending on what the team feels is the right right client-side library for them or maybe not to use the client library at all the check out is more server-side technology I believe it's using Java but I don't I'm not really sure and we have a wish list where you can add products to maybe the by later maybe in the in a store in a physical stores or to convert them into shopping cart items later and that's being written in react so just and this I think this is a very nice place to be because you're able to evolve piece by piece to different different technologies and to kind of find al like a local Maxima for the service which in turns helps us to have like a global Maxima of in terms both of the element like the teams can actually choose themselves what they want to build with depending on their their scenarios and also to learn and adapt what worked and what didn't and of all the situation and a solution from there so also in terms of performance like I said in the beginning of this talk to the favor a simple web pages as possible but as you see here the shakeout and wish list are very different from the rhetoric content and the product so to find a common way to have great performance for for this range of scenarios is it's very hard and I don't think there is a solution for it but if instead separate between services and allow each service to have their own their own style we can have a great performance as possible for each service so let's just checking time here yeah so I'll say that compared to the other like Micra front and styles of integrating things on the client side I'll say that technology diversity is it's not a it's not a bug it's a feature that you can have if you go towards this style of web development in Manatee for many teams and this is also as I believe to be the core of a general market or architecture that you allow yourself to have diversity of different technologies and that was that the promise of so a service-oriented architecture do not depend on a typical on a particular runtime like Java or.net to be able to mix and yeah so just to sum up these design constraints we are having these design constraints in our project you might not have them but if you have more than one team and one time long live the valuable solution with performance you'll have them oh yes one more thing diversity it's it's of course not great to have hundred hundred different libraries or frameworks so you have to find like a couple of them just to be just to be clear there's a diminishing return here as well that where if you have two three four that's okay but ten or twenty maybe that's over over the top because it's it's hard to share competence them between the different teams all right so these design constraints a quick recap having simple and diverse services grace gives us great per service performance which gives us a good performance as you can get with this set of services we're using transclusion to get scalable development with edge site includes as a base technology and using some Ajax for for your script components and pages and for personalized content and these style and script resources to be able to deploy CSS and JavaScript files in a good way and then to have no dependencies between the shared fragments in order to evolve the solution over the years and and that's it that's the that's my talk there are some resources here I made a kind of manifesto style web page awhile ago called Mike service websites with kind of yeah very small number of rules or constraints like as another spec but more to towards that last summer one half years ago I wrote an article over 30 pages so quite a lot of material there's a thought works tech writer blip for micro front ends it was there two times I think and there's a Twitter hashtag Micra front dance and if you want to see how I key mt Norway works there's the first URL if you just want to check out with a desktop or mobile and if you have a mobile self smartphone just go to Ikea DUP enno and you see how it works and I'm happy to answer any questions or discussions you have on Twitter after we talk so I have three minutes I think so any questions yes okay so the question was can fragment include other fragments and yes they can for for airside includes we have a naming convention so that we don't parse fragments unnecessarily so we basically have a – recursive suffix and then you're doing si resolves and inside parsing on the fragments that those kind of fragments as well and we're using that in in production as well and for for Ajax if you use if you're not using a include you have to find a way to parse the document that you're that you're having requesting but if you use H include it's just that's just a web component custom element so when the when the Dom sees another eish included in the fragment it will make another HS call for that component which is not great for performance since you have a serialized number of requests but at least it's possible and maybe you have some use cases where you have to do that the cost of your organization or other constraints but good question another question okay okay so the question was how do you go about scoping the CSS and that's also a very good question and something that I've left outside the talk so just to be clear I'm not a c6 CSS expert but I also believe that you'll having you'll have this problem of scoping CSS regardless of what way you have what Microsoft's architecture have on the front end and there exists of course many different modules ways just to make some basic thing in less or or what's order says maybe CSS magis is a good thing I'm not really a lever in the CSS in JavaScript style but maybe I'm just old-fashioned but you need to find a solution to scoping CSS so you don't pollute the global space but I won't go into details on exactly how we're doing it we're using BAM but that's not a guarantee and of course the problem is the problem with CSS it's not only of the namespaces because even the whole screen can be seen as a as a like global global resource so we live really to think about this from the ground up how you actually design for the solution to be kind of flexible enough to not have this has subtle graphical bugs as well but I'll happy to discuss after the talk and I'm afraid that the time is up so thank you so much for for listening and I will be here afterwards if you want to discuss Thanks [Applause]