Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Agular in a microservices world

2.457 Aufrufe

Veröffentlicht am

What can you do to make angular work in a microservices world

Veröffentlicht in: Technologie
  • Doctor's 2-Minute Ritual For Shocking Daily Belly Fat Loss! Watch This Video ●●● http://scamcb.com/bkfitness3/pdf
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • Do This Simple 2-Minute Ritual To Loss 1 Pound Of Belly Fat Every 72 Hours ★★★ https://tinyurl.com/y6qaaou7
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

Agular in a microservices world

  1. 1. Angular in a Microservices world Brecht Billiet @brechtbilliet
  2. 2. Hi, I’m Brecht! I help companies with web technologies... @brechtbilliet
  3. 3. I... A few references... » Kickstart projects » Give trainings/workshops » Coach companies » Do code-reviews » Do audits » Blog about stuff http://blog.brecht.io » Talk on meetups » Help with architectural decisions @brechtbilliet
  4. 4. The structural evolution of web software @brechtbilliet
  5. 5. Web application Frontend + Backend (server-side rendering) @brechtbilliet
  6. 6. We can do this! Web application Frontend + Backend (server-side rendering) @brechtbilliet
  7. 7. We can do this! We can still do this! Web application Frontend + Backend (server-side rendering) @brechtbilliet
  8. 8. We can do this! We can still do this! Err... Web application Frontend + Backend (server-side rendering) @brechtbilliet
  9. 9. Frontend Web application (spa) REST Backend Web application @brechtbilliet
  10. 10. We can do this! We can do this! REST Backend Web application Frontend Web application (spa) @brechtbilliet
  11. 11. We can still do this! We can do this! We can do this! REST Backend Web application We can still do this! Frontend Web application (spa) @brechtbilliet
  12. 12. We can still do this! We can do this! We can do this! REST Backend Web application We can still do this! Err... Err... Frontend Web application (spa) @brechtbilliet
  13. 13. Spotify engineering culture » Autonomous teams » Every team has its own ⋄ Ownership ⋄ Codebase ⋄ Build process ⋄ Deployment » Choice of tech-stack » Checkout these movies » https://labs.spotify.com/ 2014/03/27/spotify- engineering-culture-part- 1/ » https://labs.spotify.com/ 2014/09/20/spotify- engineering-culture-part- 2/ @brechtbilliet
  14. 14. Spotify engineering culture @brechtbilliet
  15. 15. Spotify engineering culture » Hard to achieve on monoliths Frontend monolith REST Backend monolith @brechtbilliet
  16. 16. Frontend Web application REST Micro Service A Micro Service Z ... » Microservices » https://martinfowler.com/articles/ microservices.html This fixes all of the “Spotify engineering culture” requirements @brechtbilliet Microservices
  17. 17. Frontend Web application REST Micro Service A Micro Service Z We can do this! We can do this! ... @brechtbilliet
  18. 18. Frontend Web application REST Micro Service A Micro Service Z ... Every team has Its own ownership Its code decoupled from the rest Its own codebase Its own repository Its own build process @brechtbilliet
  19. 19. Frontend Web application REST Micro Service A Micro Service Z ... The frontend is still a monolith @brechtbilliet
  20. 20. We want » Code splitting » Code sharing » Decoupling » Lazy loading » Separate codebases » To divide work in different teams » To give ownership to specific teams @brechtbilliet
  21. 21. Frontend Web application REST Micro Service A Micro Service Z ... We do still want a SPA (ux) @brechtbilliet
  22. 22. Frontend Web application REST Micro Service A Micro Service Z ... SPA module A But also want to give teams ownership SPA module Z ... @brechtbilliet
  23. 23. Solution one The iframe spa @brechtbilliet
  24. 24. Did he say, IFRAMES? @brechtbilliet
  25. 25. There are advantages
  26. 26. @brechtbilliet
  27. 27. Iframe 1: This belongs to team A. It contains enough code and business logic to deserve its own project @brechtbilliet
  28. 28. Iframe 2: This belongs to team B. This will be an even bigger application @brechtbilliet
  29. 29. Iframe 3: This belongs to team C. This app will be very specific @brechtbilliet
  30. 30. Orchestrator app: This application will only do communication @brechtbilliet
  31. 31. <!doctype html> <html> <head> </head> <body> <iframe src="http://myapp.com/search"></iframe> <iframe src="http://myapp.com/main"></iframe> <iframe src="http://myapp.com/player"></iframe> </body> </html> @brechtbilliet
  32. 32. How to communicate between the iframes // send a message from iframe to the orchestrator app for communication window.parent.postMessage({type: 'PLAY_SONG', data: {'title': 'Michael Jackson - Billy Jean'}}, '*'); @brechtbilliet
  33. 33. How to communicate between the iframes // send a message from iframe to the orchestrator app for communication window.parent.postMessage({type: 'PLAY_SONG', data: {'title': 'Michael Jackson - Billy Jean'}}, '*'); // send a message to the orchestrator app for communication window.addEventListener('message', receiveMessage, false); function receiveMessage(msg): void { switch(event.data.type){ case 'PLAY_SONG': // todo (set some label or whatever) } @brechtbilliet
  34. 34. Reactive is cooler =) // get a stream from all messages postMessage$ = Observable.fromEvent(window, 'message').map(res => res.data); // get a stream of the 'PLAY_SONG' messages playSongMessage$ = postMessage$.filter(item => item.type === 'PLAY_SONG'); @brechtbilliet
  35. 35. Advantages » Great isolation of code => assign to specific teams » Not tied to specific framework » Works with all different javascript technologies » Independant deploys » Ability to migrate old project easily » Easy to plug-and-play in older projects » AB-testing becomes a breeze » No code conflicts » Iframes have their own inside routing @brechtbilliet
  36. 36. Tradeoffs » Performance hit (manageable in most cases) » CSS issues, tooltips behind the iframe, ... » Drag and drop (can be fixed, but not native) » Dependencies will be loaded multiple times » Harder to share state » Only works for block-shaped elements @brechtbilliet
  37. 37. Use cases » Legacy code bases: Add ng4 project into old app in 1 line » Platforms ⋄ One application per tab ⋄ Multiple applications per tab » Independant deploys of projects Don’t overuse it! @brechtbilliet
  38. 38. Summary » Use it for specific projects (platforms, legacy codebases) » Becomes complex when too many shared state… » Share backend changes over sockets » Share state changes over document-events @brechtbilliet
  39. 39. Solution two Multiple angular apps @brechtbilliet
  40. 40. @brechtbilliet
  41. 41. Angular app Search: Owned by Team A. Exposes: ● Angular application @brechtbilliet
  42. 42. Angular app Main: Owned by Team B. Exposes: ● Angular application @brechtbilliet
  43. 43. Angular app Player: Owned by Team C. Exposes: ● Angular app @brechtbilliet
  44. 44. Orchestrator app: This application will do orchestrating @brechtbilliet
  45. 45. How to load multiple angular apps Ng4 app (cli) Ng4 app (cli) @brechtbilliet
  46. 46. How to load multiple angular apps <!doctype html> <html> <head> </head> <body> <!--These should come from a shared bundle--> <script type="text/javascript" src="somesharedbundle/dist/inline.bundle.js"></script> <!--Polyfills can only be loaded ONCE!!--> <script type="text/javascript" src="somesharedbundle/dist/polyfills.bundle.js"></script> ... </body> </html> @brechtbilliet
  47. 47. How to load multiple angular apps // create the DOM tag document.body.appendChild(document.createElement('app-courses')); // load the script from the dist folder loadScriptsSync(['courses/dist/inline.bundle.js', 'courses/dist/vendor.bundle.js', 'courses/dist/main.bundle.js']); // create the DOM tag document.body.appendChild(document.createElement('app-users')); // load the script from the dist folder loadScriptsSync(['users/dist/inline.bundle.js', 'users/dist/vendor.bundle.js', 'users/dist/main.bundle.js']); @brechtbilliet
  48. 48. How to load multiple angular apps // It’s important that the script are loaded synchronous function loadScript(path, cb) { var scriptTag = document.createElement('script'); scriptTag.src = path; scriptTag.onload = cb; scriptTag.onreadystatechange = cb; document.body.appendChild(scriptTag); } function loadScriptsSync(paths) { loadScript(paths[0], () => { loadScriptsSync(paths.filter(item => item !== paths[0])); }); } @brechtbilliet
  49. 49. Advantages » You don’t need iframes to load multiple angular apps » You can easily divide the work between teams » Independant deploys @brechtbilliet
  50. 50. Tradeoffs » No routing inside the child-apps » Can’t have multiple instances of a child-app » Not completely sandboxed » Dependencies will be loaded multiple times @brechtbilliet
  51. 51. Summary » Some people are for it, some are against it » A personal feeling: It feels a bit hacky » You can use it when you hit the limitations of an iframe (e.g css) » Routing is impossible @brechtbilliet
  52. 52. Solution three Angular modules @brechtbilliet
  53. 53. @brechtbilliet
  54. 54. Angular module Search: Owned by Team A. Exposes: ● Angular module ● Example environment @brechtbilliet
  55. 55. Angular module Main: Owned by Team B. Exposes: ● Angular module ● Example environment @brechtbilliet
  56. 56. Angular module Player: Owned by Team C. Exposes: ● Angular module ● Example environment @brechtbilliet
  57. 57. Orchestrator app: This application will do mostly routing/lazy loading @brechtbilliet
  58. 58. Angular (>2) is made for large apps It’s build as a platform framework It’s build for large teams (typescript, modules, DI) Provides: » Modules with great encapsulation » Lazy loading » Ahead-of-time compilation » A CLI (to reduce the setup process to a minimum) @brechtbilliet
  59. 59. Spotify-application (orchestrator) (angular application) Search (angular module) Main (angular module) Player (angular module) Splitting up code to specific teams NPM package NPM package NPM package @brechtbilliet
  60. 60. Spotify-application (orchestrator) (angular application) Search (angular module) Main (angular module) Player (angular module) Can be TS modules as well... NPM package NPM package NPM package Other x (TS module) Other y (TS module) NPM package NPM package @brechtbilliet
  61. 61. What does a module look like? Every module has » Its own package.json » Its own build process » Its own test environment » Its own versions » Its own test suite » Its own repo (debatable) So we can: » Assign a specific team » Have separate deploy to specific NPM registry » Lazy load them @brechtbilliet
  62. 62. The orchestration App: Module ... import { routing } from './routes'; import { SpotifySearchModule } from '@spotify-app/spotify-search'; // Npm package import { SpotifyPlayerModule } from '@spotify-app/spotify-player'; // Npm package @NgModule({ ... imports: [ routing, // here we lazy load our modules SpotifySearchModule, // directly import the angular module from npm SpotifyPlayerModule, // directly import the angular module from npm BrowserModule, ... ] }) export class MainModule {
  63. 63. The orchestration App: Routing import { PreloadAllModules, RouterModule } from '@angular/router'; export const routes = [ { path: 'foo', loadChildren: '../node_modules/@spotify-app/foo/#SpotifyFooModule' }, { path: 'bar', loadChildren: '../node_modules/@spotify-app/bar/#SpotifyBarModule' } ]; export const routing = RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }); @brechtbilliet
  64. 64. Creating a child-module » ng new spotify-player » Rename src to testenv » Create folder src, and move the source code there » Change the .angular-cli.json root property in “app” to “testenv” @brechtbilliet
  65. 65. Just use the source code (no build) » Set the Package.json main property to src/index.js index.js: export {AppModule} from './app/app.module'; @brechtbilliet
  66. 66. Advantages » Lazy loading out of the box » Module system out of the box » Creating projects is easy with the CLI » Routing + child-routing works perfectly @brechtbilliet
  67. 67. Tradeoffs » For every module deploy you also have to deploy the root application » Bound to a framework (debatable) » Not easy to combine with AOT » Not completely sandboxed, but angular provides great encapsulation @brechtbilliet
  68. 68. Last solution Bootstrap components @brechtbilliet
  69. 69. @brechtbilliet
  70. 70. Angular component Search: Owned by Team A. Exposed by Angular module Search @brechtbilliet
  71. 71. Angular component Main: Owned by Team B. Exposed by Angular module Main @brechtbilliet
  72. 72. Angular component Player: Owned by Team C. Exposed by Angular module Player @brechtbilliet
  73. 73. App (tech stack doesn’t matter) @brechtbilliet
  74. 74. Angular 1 app <search> </search> <main> </main> <player></player> Angular 4 app - spotify @brechtbilliet
  75. 75. Use multiple bootstrap components <!doctype html> <html> <head> </head> <body> <spotify-search>Loading search...</spotify-search> <spotify-main>Loading main...</spotify-main> <spotify-player>Loading player...</spotify-player> </body> </html> @brechtbilliet
  76. 76. Use multiple bootstrap components @NgModule({ ... declarations: [SearchComponent, MainComponent, PlayerComponent], imports: [BrowserModule], bootstrap: [SearchComponent, MainComponent, PlayerComponent] }) export class AppModule { } @brechtbilliet
  77. 77. Divide in teams again =) import { SearchModule } from '@spotify-app/spotify-search'; import { MainModule } from '@spotify-app/spotify-main'; import { PlayerModule } from '@spotify-app/spotify-player'; @NgModule({ ... imports: [BrowserModule, SpotifySearchModule, SpotifyMainModule, SpotifyPlayerModule], bootstrap: [SearchComponent, MainComponent, PlayerComponent] }) export class AppModule { } @brechtbilliet
  78. 78. Advantages » You can use multiple ng4 apps (as components) in a non angular application » You can combine it with the angular modules approach (same advantages) @brechtbilliet
  79. 79. Tradeoffs » Iframes still provide better encapsulation » No independant deploys (only to npm) @brechtbilliet
  80. 80. Summary » For me this is the most ideal solution @brechtbilliet
  81. 81. Questions Shoot! @brechtbilliet
  82. 82. @brechtbilliet
  83. 83. Credits This template is free to use under Creative Commons Attribution license. Thank you 4 having me! @brechtbilliet https://www.linkedin.com/in/brecht-billiet-58417426/ billietbrecht@gmail.com http://brecht.io http://blog.brecht.io http://strongbrew.io @brechtbilliet

×