Microservices in frontend:
architectures and solutions
Mikhail Kuznetcov, ING
Amsterdam, October 2019
Mikhail Kuznetcov
Developer at ING Investments
Twitter: @legkoletat
Github: github.com/shershen08
Agenda
bit.ly/ams-sve-mee
Amsterdam SvelteJS meetup
1st event 🚀
14th November
Agenda
● Microservices
● Modern frontend
● Microservice-oriented frontend solutions
● Challenges and conclusion
@legkoletat | Microservices in frontend: architectures and solutions
Microservices
@legkoletat | Microservices in frontend: architectures and solutions
Microservices
● Single responsibility principle - “granularity”
● Faster developers onboarding
● Faster adding features
● Ease of deployment*
● Freedom to choose technology*
● High scalability
@legkoletat | Microservices in frontend: architectures and solutions
Architectures
FRONTEND
BACKEND
App1 App2 App3
Infra (BFF, NGNIX, GQL,etc)
MS1
MS2
MS3
MS5
MS4
MS6
FRONTEND
+
BACKEND
@legkoletat | Microservices in frontend: architectures and solutions
Modern frontend
Modern frontends
● Complexity
● Size (100s of files, 100s of KLOC)
● Size of the teams (10s developers)
● Technological diversity
● Constant upgrades and migrations
@legkoletat | Microservices in frontend: architectures and solutions
Trend: mv complexity to front end
2005 - Django, Ruby on Rails
2006 - jQuery
2010 - AngularJS, BigPipe by Facebook
2013 - ReactJS
2016 - Micro-frontends.org, Mosaic project
2017 - Adoption of Web components
@legkoletat | Microservices in frontend: architectures and solutions
2019
thoughtworks.com/radar/te
chniques/micro-frontends
@legkoletat | Microservices in frontend: architectures and solutions
Solutions
Solutions overview
1. In-browser with single-spa
2. Server-side with tailor.js
3. iFrames / per-route apps
4. Web components as wrapper
@legkoletat | Microservices in frontend: architectures and solutions
1. In-browser: Single-spa
github.com/CanopyTax/single-spa
● In browser
● Share styles, utils, data, events etc.
● Lazy load
● Parts of one page & separate routes
● Unified lifecycle
@legkoletat | Microservices in frontend: architectures and solutions
Single-spa
Single-spa
+ config
@legkoletat | Microservices in frontend: architectures and solutions
Header app
Widget
app 1
Dashboard
app
Framefork-specific wrapper
Lazy load
Common info,
events etc
Single-spa: root config
// single-spa-config.js
import {declareChildApplication, start} from 'single-spa';
declareChildApplication('app-user-profile', () =>
import('PATH_TO/app.user.profile.js'),pathPrefix('/profile’));
declareChildApplication('app-transactions', () =>
import('PATH_TO/app.transactions.js'),pathPrefix('/transactions’));
// etc
start();
@legkoletat | Microservices in frontend: architectures and solutions
Single-spa: configure app
// app-user-profile.js
export function bootstrap(props) {
return Promise
.resolve()
.then(() => {
// one-time app initialization code
});
}
// mount callback
// unmount callback
@legkoletat | Microservices in frontend: architectures and solutions
2. Stitching fragments
github.com/zalando/tailor
● Provides complete toolset - Mosaic
● Backend powered (NodeJS)
● Serves parts of one page
@legkoletat | Microservices in frontend: architectures and solutions
Tailor.js
github.com/shershen08/tailor-vue-demo
Tailor +
Webserver
HTML-like
template
@legkoletat | Microservices in frontend: architectures and solutions
Header app
Widget
app 1
Dashboard
app
Tailor server
const Tailor = require('node-tailor');
const tailor = new Tailor({
templatesPath: '/built-apps-folder'
});
const server = http.createServer((req, res) => {
// custom server logic
tailor.requestHandler(req, res)
})
server.listen(process.env.PORT);
@legkoletat | Microservices in frontend: architectures and solutions
Tailor template
<body>
<!-- header -->
<div id="header">
<span class="fragment-error">Header failed to load</span>
</div>
<fragment src="https://abs123.company.internal.com"></fragment>
<!-- dashboard -->
<fragment src="https://dashb22.company.internal.com" primary>
</fragment>
<div class=”nav”>
Basic html here ...
</div>
@legkoletat | Microservices in frontend: architectures and solutions
3. Single app per route
● Easy to setup
● No direct interaction
● Transfer state
● Control styles
Image from Elisabeth Engel: Break Up With Your Frontend Monolith
@legkoletat | Microservices in frontend: architectures and solutions
3. iFrames
● Security
● Content adjustment - size, scroll
● Data exchange (via postMessage)
● Control styles
// app 1
window.addEventListener("message", receiveMessage, false);
// app 2
window.postMessage("hello there!", "http://example.com");
@legkoletat | Microservices in frontend: architectures and solutions
App per route / iframe
No SPA
State: via server or request
params
@legkoletat | Microservices in frontend: architectures and solutions
Header app
Widget
app 1
Dashboard
app
Widget
app 2
Header
4. Framework + Web components
● DOM & styles can be isolated
● From single components to full apps
● Widespread and supported
@legkoletat | Microservices in frontend: architectures and solutions
Framework + Web components
github.com/vuejs/vue-web-component-wrapper
Example for Vue, same can be for Angular, React, Svelte, etc
@legkoletat | Microservices in frontend: architectures and solutions
Glimpse of future: Portals
<portal id="myPortal" src="https://www.example.com/"></portal>
github.com/WICG
@legkoletat | Microservices in frontend: architectures and solutions
Secure and seamless navigation
Portal can be activated
myPortal.activate({ data: [...] });
Other document (portal) listens to activation, loads data and react
window.addEventListener('portalactivate', e => {
let predecessor = e.adoptPredecessor(document);
// etc
Challenges &
conclusions
We can solve any problem by introducing an extra
level of indirection Fundamental theorem of software engineering
Technical challenges
● More complex setup
● Managing state and passing data & events
● Predictable and reusable styles
● Page code size (TTI, loading, debugging)
var bus = new EventBus();
bus.on('someEvent', function (data) {
console.log('got ' + data);
});
bus.on('someEvent', function foo () {
bus.off('someEvent', foo);
});
@legkoletat | Microservices in frontend: architectures and solutions
Pros
Single responsibility principle
Fast onboarding and adding features
Ease of testing, deployment
Freedom to choose technology*
@legkoletat | Microservices in frontend: architectures and solutions
Do you really need this?
1. Business profile
2. Application usage profile
3. Size of codebase
4. Infrastructure
5. Size, stablity and maturity of team
@legkoletat | Microservices in frontend: architectures and solutions
Thank you! Questions?
@legkoletatPresentation PDF on Slideshare
bit.ly
/microfronts
Approach in ING
● Multitude of apps using AngularJS, Polymer, lit-html
● Migration approach: single app per route
● Use combination of custom web components library
@legkoletat | Microservices in frontend: architectures and solutions
Deployment process
● Single repo -> single pipeline ->
● Variety in one area → variety in all areas
● Integration testing becvomes complex
@legkoletat
https://www.upwork.
com/blog/2017/05/m
odernizing-upwork-
micro-frontends/
Micro frontends (2016)
https://micro-frontends.org/
@legkoletat
Comparison of the approaches
Server
based
Frontend
based
Hybrid
(app per
page.
iframe)
@legkoletat | Microservices in frontend: architectures and solutions

Front end microservices - October 2019

  • 1.
    Microservices in frontend: architecturesand solutions Mikhail Kuznetcov, ING Amsterdam, October 2019
  • 2.
    Mikhail Kuznetcov Developer atING Investments Twitter: @legkoletat Github: github.com/shershen08 Agenda
  • 3.
  • 4.
    Agenda ● Microservices ● Modernfrontend ● Microservice-oriented frontend solutions ● Challenges and conclusion @legkoletat | Microservices in frontend: architectures and solutions
  • 5.
  • 6.
    @legkoletat | Microservicesin frontend: architectures and solutions
  • 7.
    Microservices ● Single responsibilityprinciple - “granularity” ● Faster developers onboarding ● Faster adding features ● Ease of deployment* ● Freedom to choose technology* ● High scalability @legkoletat | Microservices in frontend: architectures and solutions
  • 9.
    Architectures FRONTEND BACKEND App1 App2 App3 Infra(BFF, NGNIX, GQL,etc) MS1 MS2 MS3 MS5 MS4 MS6 FRONTEND + BACKEND @legkoletat | Microservices in frontend: architectures and solutions
  • 10.
  • 11.
    Modern frontends ● Complexity ●Size (100s of files, 100s of KLOC) ● Size of the teams (10s developers) ● Technological diversity ● Constant upgrades and migrations @legkoletat | Microservices in frontend: architectures and solutions
  • 13.
    Trend: mv complexityto front end 2005 - Django, Ruby on Rails 2006 - jQuery 2010 - AngularJS, BigPipe by Facebook 2013 - ReactJS 2016 - Micro-frontends.org, Mosaic project 2017 - Adoption of Web components @legkoletat | Microservices in frontend: architectures and solutions
  • 14.
  • 15.
  • 16.
    Solutions overview 1. In-browserwith single-spa 2. Server-side with tailor.js 3. iFrames / per-route apps 4. Web components as wrapper @legkoletat | Microservices in frontend: architectures and solutions
  • 17.
    1. In-browser: Single-spa github.com/CanopyTax/single-spa ●In browser ● Share styles, utils, data, events etc. ● Lazy load ● Parts of one page & separate routes ● Unified lifecycle @legkoletat | Microservices in frontend: architectures and solutions
  • 18.
    Single-spa Single-spa + config @legkoletat |Microservices in frontend: architectures and solutions Header app Widget app 1 Dashboard app Framefork-specific wrapper Lazy load Common info, events etc
  • 19.
    Single-spa: root config //single-spa-config.js import {declareChildApplication, start} from 'single-spa'; declareChildApplication('app-user-profile', () => import('PATH_TO/app.user.profile.js'),pathPrefix('/profile’)); declareChildApplication('app-transactions', () => import('PATH_TO/app.transactions.js'),pathPrefix('/transactions’)); // etc start(); @legkoletat | Microservices in frontend: architectures and solutions
  • 20.
    Single-spa: configure app //app-user-profile.js export function bootstrap(props) { return Promise .resolve() .then(() => { // one-time app initialization code }); } // mount callback // unmount callback @legkoletat | Microservices in frontend: architectures and solutions
  • 21.
    2. Stitching fragments github.com/zalando/tailor ●Provides complete toolset - Mosaic ● Backend powered (NodeJS) ● Serves parts of one page @legkoletat | Microservices in frontend: architectures and solutions
  • 22.
    Tailor.js github.com/shershen08/tailor-vue-demo Tailor + Webserver HTML-like template @legkoletat |Microservices in frontend: architectures and solutions Header app Widget app 1 Dashboard app
  • 23.
    Tailor server const Tailor= require('node-tailor'); const tailor = new Tailor({ templatesPath: '/built-apps-folder' }); const server = http.createServer((req, res) => { // custom server logic tailor.requestHandler(req, res) }) server.listen(process.env.PORT); @legkoletat | Microservices in frontend: architectures and solutions
  • 24.
    Tailor template <body> <!-- header--> <div id="header"> <span class="fragment-error">Header failed to load</span> </div> <fragment src="https://abs123.company.internal.com"></fragment> <!-- dashboard --> <fragment src="https://dashb22.company.internal.com" primary> </fragment> <div class=”nav”> Basic html here ... </div> @legkoletat | Microservices in frontend: architectures and solutions
  • 25.
    3. Single appper route ● Easy to setup ● No direct interaction ● Transfer state ● Control styles Image from Elisabeth Engel: Break Up With Your Frontend Monolith @legkoletat | Microservices in frontend: architectures and solutions
  • 26.
    3. iFrames ● Security ●Content adjustment - size, scroll ● Data exchange (via postMessage) ● Control styles // app 1 window.addEventListener("message", receiveMessage, false); // app 2 window.postMessage("hello there!", "http://example.com"); @legkoletat | Microservices in frontend: architectures and solutions
  • 27.
    App per route/ iframe No SPA State: via server or request params @legkoletat | Microservices in frontend: architectures and solutions Header app Widget app 1 Dashboard app Widget app 2 Header
  • 28.
    4. Framework +Web components ● DOM & styles can be isolated ● From single components to full apps ● Widespread and supported @legkoletat | Microservices in frontend: architectures and solutions
  • 29.
    Framework + Webcomponents github.com/vuejs/vue-web-component-wrapper Example for Vue, same can be for Angular, React, Svelte, etc @legkoletat | Microservices in frontend: architectures and solutions
  • 30.
    Glimpse of future:Portals <portal id="myPortal" src="https://www.example.com/"></portal> github.com/WICG @legkoletat | Microservices in frontend: architectures and solutions Secure and seamless navigation Portal can be activated myPortal.activate({ data: [...] }); Other document (portal) listens to activation, loads data and react window.addEventListener('portalactivate', e => { let predecessor = e.adoptPredecessor(document); // etc
  • 31.
  • 32.
    We can solveany problem by introducing an extra level of indirection Fundamental theorem of software engineering
  • 33.
    Technical challenges ● Morecomplex setup ● Managing state and passing data & events ● Predictable and reusable styles ● Page code size (TTI, loading, debugging) var bus = new EventBus(); bus.on('someEvent', function (data) { console.log('got ' + data); }); bus.on('someEvent', function foo () { bus.off('someEvent', foo); }); @legkoletat | Microservices in frontend: architectures and solutions
  • 34.
    Pros Single responsibility principle Fastonboarding and adding features Ease of testing, deployment Freedom to choose technology* @legkoletat | Microservices in frontend: architectures and solutions
  • 35.
    Do you reallyneed this? 1. Business profile 2. Application usage profile 3. Size of codebase 4. Infrastructure 5. Size, stablity and maturity of team @legkoletat | Microservices in frontend: architectures and solutions
  • 36.
    Thank you! Questions? @legkoletatPresentationPDF on Slideshare bit.ly /microfronts
  • 38.
    Approach in ING ●Multitude of apps using AngularJS, Polymer, lit-html ● Migration approach: single app per route ● Use combination of custom web components library @legkoletat | Microservices in frontend: architectures and solutions
  • 40.
    Deployment process ● Singlerepo -> single pipeline -> ● Variety in one area → variety in all areas ● Integration testing becvomes complex @legkoletat https://www.upwork. com/blog/2017/05/m odernizing-upwork- micro-frontends/
  • 41.
  • 42.
    Comparison of theapproaches Server based Frontend based Hybrid (app per page. iframe) @legkoletat | Microservices in frontend: architectures and solutions