Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Microservice Websites – Micro CPH

407 views

Published on

How can we develop websites where the different parts of the pages are developed by different teams? If you work in a large enough organization which has its content and services on the web, this is probably a question you have asked yourself several times.

With this talk I want to show that server-side rendered websites integrated on content (using transclusion) allow for high long-term evolvability compared to client-side rendering integrated with shared code. In other words, if you want a system with high long-term evolvability, you should not develop websites using only client-side JavaScript and integrate them using a shared components approach.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Microservice Websites – Micro CPH

  1. 1. MICROSERVICE WEBSITES Gustaf Nilsson Kotte @gustaf_nk
  2. 2. Mobile devices The problem
  3. 3. How can we develop a website with multiple teams? Different business units need to make a website together that should feel like “one website” for the end-user. Example: Retail domain Products, Shopping cart, Checkout, Recommendations, Reviews, User profile, Editorial content, etc... The problem
  4. 4. Decentralized services but centralized web? Frontend Bottleneck
  5. 5. Services should have their own frontend! Stefan Tilkov et al, “Self-Contained Systems” Frontend Frontend FrontendFrontend Autonomy → Continuous delivery
  6. 6. Decentralized governance An option for teams to choose different tools → heterogeneous/plural/diverse system High rate of change on the frontend Allows the system to evolve over time James Lewis & Martin Fowler, “Microservices: Decentralized Governance”
  7. 7. Addy Osmani, “JavaScript Start-up Performance” Mobile device performance
  8. 8. Constraints (need to support) Continuous delivery Decentralized governance Good performance on mobile devices Microservice Websites
  9. 9. Mobile devices Analysis
  10. 10. INTEGRATION USE CASE Shopping cart How can we reuse the shopping cart between different parts of the web site? “Many-to-one” Multiple teams – one shopping cart
  11. 11. INTEGRATION USE CASE Landing page The web site’s landing page is the page with the most amount of traffic and many business units want to be represented there. “One-to-many” Multiple teams – one landing page
  12. 12. Integrating on... What (data/code/content) When (build/run) Where (client/server) Cartesian product → 12 combinations Let’s go through them! Analysis
  13. 13. What × when × where What? When? Where? Data (APIs) Build Client Server Run Client Server Code (JavaScript, PHP, etc) Build Client Server Run Client Server Content (HTML) Build Client Server Run Client Server What × when × where
  14. 14. What × when × where What? When? Where? Data (APIs) Build Client No reuse at all, only API usage Server Run Client Server Code (JavaScript, PHP, etc) Build Client Server Run Client Server Content (HTML) Build Client Server Run Client Server What × when × where
  15. 15. What × when × where What? When? Where? Data (APIs) Build Client No reuse at all, only API usage Server Run Client Server Code (JavaScript, PHP, etc) Build Client No continuous delivery. No diversity + mobile performance. Server Run Client Server Content (HTML) Build Client Server Run Client Server What × when × where
  16. 16. What × when × where What? When? Where? Data (APIs) Build Client No reuse at all, only API usage Server Run Client Server Code (JavaScript, PHP, etc) Build Client No continuous delivery. No diversity + mobile performance. Server Run Client No diversity + mobile performance. Server N/A Content (HTML) Build Client Server Run Client Server What × when × where
  17. 17. What × when × where What? When? Where? Data (APIs) Build Client No reuse at all, only API usage Server Run Client Server Code (JavaScript, PHP, etc) Build Client No continuous delivery. No diversity + mobile performance. Server Run Client No diversity + mobile performance. Server N/A Content (HTML) Build Client Server Run Client Server What × when × where
  18. 18. What × when × where What? When? Where? Data (APIs) Build Client No reuse at all, only API usage Server Run Client Server Code (JavaScript, PHP, etc) Build Client No continuous delivery. No diversity + mobile performance Server Run Client No diversity + mobile performance. Server N/A Content (HTML) Build Client N/A Server “Static page fragments” – ok, but limited amount of use cases Run Client Server What × when × where
  19. 19. What × when × where What? When? Where? Data (APIs) Build Client No reuse at all, only API usage Server Run Client Server Code (JavaScript, PHP, etc) Build Client No continuous delivery. No diversity + mobile performance. Server Run Client No diversity + mobile performance. Server N/A Content (HTML) Build Client N/A Server “Static page fragments” – ok, but limited amount of use cases Run Client Client-side transclusion Server Server-side transclusion What × when × where
  20. 20. What? When? Where? Data (APIs) Build Client No reuse at all, only API usage Server Run Client Server Code (JavaScript, PHP, etc) Build Client No continuous delivery. No diversity + mobile performance. Server Run Client No diversity + mobile performance. Server N/A Content (HTML) Build Client N/A Server “Static page fragments” – ok, but limited amount of use cases Run Client Client-side transclusion Server Server-side transclusion What × when × whereWhat × when × where
  21. 21. Mobile devices Transclusion
  22. 22. Transclusion “transclusion is the inclusion of part or all of an electronic document into one or more other documents by hypertext reference” (Wikipedia: Transclusion) Producer Expose a fragment resource, "/retail/shopping-cart/" Consumer Include the fragment declaratively, similar to <img src="..." /> Transclusion can be used both on server and client Examples: Edge-Side Includes (server) and <h-include> (client)
  23. 23. Edge Side Includes (server) <-- Include the shopping cart component --> <esi:include src="/retail/shopping-cart/" /> ESI 1.0 proposal submitted to W3C 2001 CDN support: Akamai, Fastly On-premise support: Varnish, Squid, nodesi, etc
  24. 24. <h-include> (client) <h-include src="/retail/shopping-cart/"></h-include> Custom Elements version of hinclude.js (by Mark Nottingham, 2006) Difference: interface and transitive includes HTTP/2 → Bundles multiple xhr requests into one Both support refresh()
  25. 25. ESI (server) + SEO + JS/CSS in responses works as usual + Initial performance + Cross-domain requests - Extra infrastructure investment - Dev perspective (+ i.e. nodesi) - No streamed responses ⇒ blocking - Performance sensitive (+ timeouts) - No header forwarding (+ configuration) Server transclusion vs client transclusion h-include (client) - No SEO - No loading of JS/CSS in responses - Delay before xhr requests arrive - No cross-domain requests (unless CORS) - If no initial width/height, page will “jump” + No extra infrastructure investment + No extra dev setup + Async ⇒ non-blocking + Responses are rendered when they arrive + Headers work as usual in browsers
  26. 26. ESI and h-include together (1) // Refresh-only h-include var proto = Object.create(HIncludeElement.prototype); proto.attachedCallback = function() { /* do nothing */ }; document.registerElement('h-include-refresh-only', { prototype: proto, }); ⇒ <h-include-refresh-only src="...">REFRESHABLE CONTENT HERE</h-include-refresh-only> Allows us to wrap the ESI fragment response in an h-include-refresh-only ⇒ server-side initial content with client-side refreshes
  27. 27. ESI and h-include together (2) // Lazy-loading with hunt.js window.addEventListener('load', function() { // For these elements... hunt(document.getElementsByTagName('h-include-refresh-only'), { // ...when they’re almost in the viewport... offset: 400, // ...load them! in: function() { this.refresh(); }, }); });
  28. 28. Constraints (need to support) Continuous delivery Decentralized governance Good performance on mobile devices Rules for integration Transclude server-side resources Microservice Websites
  29. 29. Mobile devices Client-side dependencies
  30. 30. Shopping cart HTML, check! But, what about... Additional client-side behavior? (JavaScript) Design? (CSS)
  31. 31. How to import service dependencies Still need cache busting (i.e. /retail/shopping-cart/scripts-aef419.js) Server-side transclusion works well here Client-side transclusion require either 1) HTTP redirects, or 2) “loaders” like little-loader for JS and loadCSS for CSS. Both options are less performant than using server-side transclusion, because of extra client/server roundtrips.
  32. 32. <head> ... <!-- Include shopping cart resources (cache-busting-as-a-service) --> <esi:include src="/retail/shopping-cart/stylesheets/" /> ... </head> <body> ... <-- Include the shopping cart component --> <esi:include src="/retail/shopping-cart/" /> … <esi:include src="/retail/shopping-cart/scripts/" /> </body> Load dependencies (before transclusion)
  33. 33. <head> ... <!-- Include shopping cart resources (cache-busting-as-a-service) --> <link rel="stylesheet" src="/retail/shopping-cart/style-ffc864.css" /> ... </head> <body> ... <-- Include the shopping cart component --> <div class="shopping-cart">Hello, shopping cart</div> ... <script src="/retail/shopping-cart/scripts-aef419.js"></script> </body> Load dependencies (after transclusion)
  34. 34. Client-side dependencies: JavaScript No assumptions of consuming services’ client-side dependencies ⇒ Vanilla JS + polyfills (neither are “free”, so use both with care) Custom Elements simplifies the lifecycle of components https://github.com/WebReflection/document-register-element (5 KB)
  35. 35. Client-side dependencies: CSS Disclaimer: I’m not a CSS expert Large-scale CSS development is hard (but what’s the alternative?) Styleguide Namespacing/components/responsive/flexible Good news: others have this problem too (i.e. “multi-team SPAs”) Small global dependency for resets and typography (optional)
  36. 36. Constraints (need to support) Continuous delivery Decentralized governance Good performance on mobile devices Rules for integration Transclude server-side resources No global client-side dependencies Microservice Websites
  37. 37. Mobile devices Summary
  38. 38. Services should have their own frontend! Frontend Frontend FrontendFrontend Integration: Transclusion
  39. 39. Constraints (need to support) Continuous delivery Decentralized governance (otherwise: “occasional” rewrites) Good performance on mobile devices Rules for integration (free to use JS frameworks internally, but not for exported fragments) Transclude server-side resources No global client-side dependencies Microservice Websites
  40. 40. Further resources Microservice Websites, Gustaf Nilsson Kotte Microservices, James Lewis & Martin Fowler Self-Contained Systems, Stefan Tilkov et al. Architecture Without an End State, Michael Nygard JavaScript Start-up Performance, Addi Osmani Also, this is a great book: I’ll happily chat on twitter: @gustaf_nk

×