{"id":2384,"date":"2018-04-03T15:16:10","date_gmt":"2018-04-03T13:16:10","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=2384"},"modified":"2018-04-03T15:16:10","modified_gmt":"2018-04-03T13:16:10","slug":"a-lightweight-and-solid-approach","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/","title":{"rendered":"A Lightweight And Solid Approach"},"content":{"rendered":"<div class=\"article\">\n<p>Even though the word iframe causes bad feelings for most web devs, it turns out that using them for building SPAs for micro services -- aka <a href=\"https:\/\/micro-frontends.org\/\" rel=\"nofollow\">micro frontends<\/a> -- is a good choice. For instance, they allow for a <strong>perfect isolation<\/strong> between clients and for a separate deployment. Because of the isolation they also allow using different SPA frameworks. Besides iframes, there are other approaches to use SPAs in micro service architectures -- of course, each of them has their own pros and cons. A good <a href=\"https:\/\/medium.com\/@tomsoderlund\/micro-frontends-a-microservice-approach-to-front-end-web-development-f325ebdadc16\" rel=\"nofollow\">overview<\/a> can be found <a href=\"https:\/\/medium.com\/@tomsoderlund\/micro-frontends-a-microservice-approach-to-front-end-web-development-f325ebdadc16\" rel=\"nofollow\">here<\/a>. Another great resource comparing the options available is <a href=\"https:\/\/twitter.com\/brechtbilliet?lang=de\" rel=\"nofollow\">Brecht Billiet<\/a>'s <a href=\"https:\/\/de.slideshare.net\/BrechtBilliet\/agular-in-a-microservices-world\" rel=\"nofollow\">presentation about this topic<\/a>.<\/p>\n<p>In addition to this, I've written <a href=\"https:\/\/www.angulararchitects.io\/post\/2017\/12\/28\/a-software-architect-s-approach-towards-using-angular-and-spas-in-general-for-microservices-aka-microfrontends.aspx\">another blog post comparing several approaches by evaluating them against some selected architectural goals<\/a>.<\/p>\n<p>As <a href=\"https:\/\/twitter.com\/jawache?lang=de\" rel=\"nofollow\">Asim Hussain<\/a> shows in this <a href=\"https:\/\/codecraft.tv\/blog\/2017\/09\/07\/angularjs-to-angular-using-iframes\/\" rel=\"nofollow\">blog article<\/a>, using iframes can also be a nice solution for migrating an existing AngularJS application to Angular.<\/p>\n<p>For the approach described here, I've written a \"meta router\" to load different spa clients for micro services in iframes. It takes care about the iframe's creation and about synchronizing their routes with the shell's url. It also resizes the iframe dynamically to prevent a scrolling bar within it. The library is written in a framework agnostic way.<\/p>\n<p>The router can be <a href=\"https:\/\/www.npmjs.com\/package\/meta-spa-router\" rel=\"nofollow\">installed via npm<\/a>:<\/p>\n<pre><code>npm install meta-spa-router --save\n<\/code><\/pre>\n<p>The <a href=\"https:\/\/github.com\/manfredsteyer\/meta-router\">source code and an example<\/a> can be found in <a href=\"https:\/\/github.com\/manfredsteyer\/meta-router\">my GitHub account<\/a>.<\/p>\n<p>In the example I'm using VanillaJS for the shell application and Angular for the routed child apps.<\/p>\n<p>This is how to set up the shell with VanillaJS:<\/p>\n<div class=\"\">\n<pre><span class=\"pl-k\">var<\/span> MetaRouter <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">require<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>meta-spa-router<span class=\"pl-pds\">'<\/span><\/span>).<span class=\"pl-smi\">MetaRouter<\/span>;\n\n<span class=\"pl-k\">var<\/span> config <span class=\"pl-k\">=<\/span> [\n    {\n        path<span class=\"pl-k\">:<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>a<span class=\"pl-pds\">'<\/span><\/span>,\n        app<span class=\"pl-k\">:<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>\/app-a\/dist<span class=\"pl-pds\">'<\/span><\/span>\n    },\n    {\n        path<span class=\"pl-k\">:<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>b<span class=\"pl-pds\">'<\/span><\/span>,\n        app<span class=\"pl-k\">:<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>\/app-b\/dist<span class=\"pl-pds\">'<\/span><\/span>\n    }\n];\n\n<span class=\"pl-c1\">window<\/span>.<span class=\"pl-c1\">addEventListener<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>load<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-k\">function<\/span>() { \n\n    <span class=\"pl-k\">var<\/span> router <span class=\"pl-k\">=<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-en\">MetaRouter<\/span>();\n    <span class=\"pl-smi\">router<\/span>.<span class=\"pl-en\">config<\/span>(config);\n    <span class=\"pl-smi\">router<\/span>.<span class=\"pl-en\">init<\/span>();\n    <span class=\"pl-smi\">router<\/span>.<span class=\"pl-en\">preload<\/span>();\n\n    <span class=\"pl-c1\">document<\/span>.<span class=\"pl-c1\">getElementById<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>link-a<span class=\"pl-pds\">'<\/span><\/span>)\n            .<span class=\"pl-c1\">addEventListener<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>click<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-k\">function<\/span>() { <span class=\"pl-smi\">router<\/span>.<span class=\"pl-c1\">go<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>a<span class=\"pl-pds\">'<\/span><\/span>) });\n\n    <span class=\"pl-c1\">document<\/span>.<span class=\"pl-c1\">getElementById<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>link-b<span class=\"pl-pds\">'<\/span><\/span>)\n            .<span class=\"pl-c1\">addEventListener<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>click<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-k\">function<\/span>() { <span class=\"pl-smi\">router<\/span>.<span class=\"pl-c1\">go<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>b<span class=\"pl-pds\">'<\/span><\/span>) });\n\n    <span class=\"pl-c1\">document<\/span>.<span class=\"pl-c1\">getElementById<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>link-aa<span class=\"pl-pds\">'<\/span><\/span>)\n            .<span class=\"pl-c1\">addEventListener<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>click<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-k\">function<\/span>() { <span class=\"pl-smi\">router<\/span>.<span class=\"pl-c1\">go<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>a<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>a<span class=\"pl-pds\">'<\/span><\/span>) });\n\n            <span class=\"pl-c1\">document<\/span>.<span class=\"pl-c1\">getElementById<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>link-ab<span class=\"pl-pds\">'<\/span><\/span>)\n            .<span class=\"pl-c1\">addEventListener<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>click<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-k\">function<\/span>() { <span class=\"pl-smi\">router<\/span>.<span class=\"pl-c1\">go<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>a<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>b<span class=\"pl-pds\">'<\/span><\/span>) });        \n\n}); <\/pre>\n<\/div>\n<p>And here is the HTML for the shell:<\/p>\n<div class=\"highlight-text-html-basic\">\n<pre>&lt;<span class=\"pl-ent\">div<\/span>&gt;\n    &lt;<span class=\"pl-ent\">a<\/span> <span class=\"pl-e\">id<\/span>=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>link-a<span class=\"pl-pds\">\"<\/span><\/span>&gt;Route to A&lt;\/<span class=\"pl-ent\">a<\/span>&gt; |\n    &lt;<span class=\"pl-ent\">a<\/span> <span class=\"pl-e\">id<\/span>=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>link-b<span class=\"pl-pds\">\"<\/span><\/span>&gt;Route to B&lt;\/<span class=\"pl-ent\">a<\/span>&gt; |\n    &lt;<span class=\"pl-ent\">a<\/span> <span class=\"pl-e\">id<\/span>=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>link-aa<span class=\"pl-pds\">\"<\/span><\/span>&gt;Jump to A within A&lt;\/<span class=\"pl-ent\">a<\/span>&gt; |\n    &lt;<span class=\"pl-ent\">a<\/span> <span class=\"pl-e\">id<\/span>=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>link-ab<span class=\"pl-pds\">\"<\/span><\/span>&gt;Jump to B within A&lt;\/<span class=\"pl-ent\">a<\/span>&gt;\n&lt;\/<span class=\"pl-ent\">div<\/span>&gt;\n\n<span class=\"pl-c\"><span class=\"pl-c\">&lt;!--<\/span> placeholder for routed apps <span class=\"pl-c\">--&gt;<\/span><\/span>\n&lt;<span class=\"pl-ent\">div<\/span> <span class=\"pl-e\">id<\/span>=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>outlet<span class=\"pl-pds\">\"<\/span><\/span>&gt;&lt;\/<span class=\"pl-ent\">div<\/span>&gt;<\/pre>\n<\/div>\n<p>The router creates the iframes as children of the element with the id <code>outlet<\/code> and allows switching between them using the method <code>go<\/code>. As you see in the example, it also allows to jump to a subroute within an application.<\/p>\n<p>The routed applications use the <code>RoutedApp<\/code> class to establish a connection with the shell. This is necessary to sync the client app's router with the shell's one. As I'm using Angular in my example, I'm registering it as a service. Instead of this, one could also directly instantiate it when going with other frameworks.<\/p>\n<p>To register this service that comes without Angular Metadata for AOT because its framework agnostic, I'm creating a token in a new file <code>app.tokens.ts<\/code>:<\/p>\n<div class=\"highlight-source-ts\">\n<pre><span class=\"pl-k\">import<\/span> { <span class=\"pl-smi\">RoutedApp<\/span> } <span class=\"pl-k\">from<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>meta-spa-router<span class=\"pl-pds\">'<\/span><\/span>;\n<span class=\"pl-k\">import<\/span> { <span class=\"pl-smi\">InjectionToken<\/span> } <span class=\"pl-k\">from<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>@angular\/core<span class=\"pl-pds\">'<\/span><\/span>;\n\n<span class=\"pl-k\">export<\/span> <span class=\"pl-k\">const<\/span> ROUTED_APP <span class=\"pl-k\">=<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-en\">InjectionToken<\/span>&lt;<span class=\"pl-en\">RoutedApp<\/span>&gt;(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>ROUTED_APP<span class=\"pl-pds\">'<\/span><\/span>);<\/pre>\n<\/div>\n<p>Then I'm using it to create a service provider for the <code>RoutedApp<\/code> class:<\/p>\n<div class=\" highlight-source-ts\">\n<pre><span class=\"pl-k\">import<\/span> { <span class=\"pl-smi\">RoutedApp<\/span> } <span class=\"pl-k\">from<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>meta-spa-router<span class=\"pl-pds\">'<\/span><\/span>;\n[<span class=\"pl-k\">...<\/span>]\n\n@<span class=\"pl-en\">NgModule<\/span>({\n  [<span class=\"pl-k\">...<\/span>],  \n  providers: [{ provide: <span class=\"pl-c1\">ROUTED_APP<\/span>, <span class=\"pl-en\">useFactory<\/span>: () <span class=\"pl-k\">=&gt;<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-en\">RoutedApp<\/span>() }],\n  bootstrap: [<span class=\"pl-smi\">AppComponent<\/span>]\n})\n<span class=\"pl-k\">export<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-en\">AppModule<\/span> { }\n<\/pre>\n<\/div>\n<p>In the <code>AppComponent<\/code> I'm getting hold of a <code>RoutedApp<\/code> instance by using dependency injection:<\/p>\n<div class=\" highlight-source-ts\">\n<pre><span class=\"pl-c\"><span class=\"pl-c\">\/\/<\/span> app.component.ts in routed app<\/span>\n<span class=\"pl-c\"><\/span>\n<span class=\"pl-k\">import<\/span> { <span class=\"pl-smi\">Router<\/span>, <span class=\"pl-smi\">NavigationEnd<\/span> } <span class=\"pl-k\">from<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>@angular\/router<span class=\"pl-pds\">'<\/span><\/span>;\n<span class=\"pl-k\">import<\/span> { <span class=\"pl-smi\">Component<\/span> } <span class=\"pl-k\">from<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>@angular\/core<span class=\"pl-pds\">'<\/span><\/span>;\n<span class=\"pl-k\">import<\/span> { <span class=\"pl-smi\">filter<\/span> } <span class=\"pl-k\">from<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>rxjs\/operators<span class=\"pl-pds\">'<\/span><\/span>;\n<span class=\"pl-k\">import<\/span> { <span class=\"pl-smi\">RoutedApp<\/span> } <span class=\"pl-k\">from<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>meta-spa-router<span class=\"pl-pds\">'<\/span><\/span>;\n\n@<span class=\"pl-en\">Component<\/span>({\n  selector: <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>app-root<span class=\"pl-pds\">'<\/span><\/span>,\n  templateUrl: <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>.\/app.component.html<span class=\"pl-pds\">'<\/span><\/span>,\n  styleUrls: [<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>.\/app.component.css<span class=\"pl-pds\">'<\/span><\/span>]\n})\n<span class=\"pl-k\">export<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-en\">AppComponent<\/span> {\n  title <span class=\"pl-k\">=<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>app<span class=\"pl-pds\">'<\/span><\/span>;\n\n  <span class=\"pl-k\">constructor<\/span>(\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-v\">router<\/span><span class=\"pl-k\">:<\/span> <span class=\"pl-en\">Router<\/span>, \n    @<span class=\"pl-en\">Inject<\/span>(<span class=\"pl-c1\">ROUTED_APP<\/span>) <span class=\"pl-k\">private<\/span> <span class=\"pl-v\">routedApp<\/span><span class=\"pl-k\">:<\/span> <span class=\"pl-en\">RoutedApp<\/span>) {\n    <span class=\"pl-c1\">this<\/span>.<span class=\"pl-en\">initRoutedApp<\/span>();\n  }\n\n  initRoutedApp() {\n\n    <span class=\"pl-c1\">this<\/span>.<span class=\"pl-smi\">routedApp<\/span>.<span class=\"pl-en\">config<\/span>({ appId: <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>a<span class=\"pl-pds\">'<\/span><\/span> });\n    <span class=\"pl-c1\">this<\/span>.<span class=\"pl-smi\">routedApp<\/span>.<span class=\"pl-en\">init<\/span>();\n\n    <span class=\"pl-c1\">this<\/span>.<span class=\"pl-smi\">router<\/span>.<span class=\"pl-smi\">events<\/span>.<span class=\"pl-en\">pipe<\/span>(<span class=\"pl-en\">filter<\/span>(<span class=\"pl-v\">e<\/span> <span class=\"pl-k\">=&gt;<\/span> <span class=\"pl-smi\">e<\/span> <span class=\"pl-k\">instanceof<\/span> <span class=\"pl-smi\">NavigationEnd<\/span>)).<span class=\"pl-en\">subscribe<\/span>((<span class=\"pl-v\">e<\/span><span class=\"pl-k\">:<\/span> <span class=\"pl-en\">NavigationEnd<\/span>) <span class=\"pl-k\">=&gt;<\/span> {\n      <span class=\"pl-c1\">this<\/span>.<span class=\"pl-smi\">routedApp<\/span>.<span class=\"pl-en\">sendRoute<\/span>(<span class=\"pl-smi\">e<\/span>.<span class=\"pl-smi\">url<\/span>);\n    });\n\n    <span class=\"pl-c1\">this<\/span>.<span class=\"pl-smi\">routedApp<\/span>.<span class=\"pl-en\">registerForRouteChange<\/span>(<span class=\"pl-v\">url<\/span> <span class=\"pl-k\">=&gt;<\/span> <span class=\"pl-c1\">this<\/span>.<span class=\"pl-smi\">router<\/span>.<span class=\"pl-en\">navigateByUrl<\/span>(<span class=\"pl-smi\">url<\/span>));\n  }\n\n}<\/pre>\n<\/div>\n<p>I'm assigning an <code>appId<\/code> which is by convention the same as the child app's path in the shell. In addition to that, I'm also synchronizing the meta router with the child's apps one.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Towards Micro Frontends (Micro Service Clients) With Angular And\/Or Other Frameworks<\/p>\n","protected":false},"author":9,"featured_media":2997,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2384","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-unkategorisiert"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A Lightweight And Solid Approach - ANGULARarchitects<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Lightweight And Solid Approach - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"Towards Micro Frontends (Micro Service Clients) With Angular And\/Or Other Frameworks\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2018-04-03T13:16:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"853\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer, GDE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@daniel\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer, GDE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/\"},\"author\":{\"name\":\"Manfred Steyer, GDE\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\"},\"headline\":\"A Lightweight And Solid Approach\",\"datePublished\":\"2018-04-03T13:16:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/\"},\"wordCount\":454,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"articleSection\":[\"Unkategorisiert\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/\",\"name\":\"A Lightweight And Solid Approach - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"datePublished\":\"2018-04-03T13:16:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"width\":1280,\"height\":853},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Lightweight And Solid Approach\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\",\"name\":\"Manfred Steyer, GDE\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer, GDE\"},\"sameAs\":[\"https:\/\/x.com\/daniel\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A Lightweight And Solid Approach - ANGULARarchitects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/","og_locale":"en_US","og_type":"article","og_title":"A Lightweight And Solid Approach - ANGULARarchitects","og_description":"Towards Micro Frontends (Micro Service Clients) With Angular And\/Or Other Frameworks","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/","og_site_name":"ANGULARarchitects","article_published_time":"2018-04-03T13:16:10+00:00","og_image":[{"width":1280,"height":853,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer, GDE","twitter_card":"summary_large_image","twitter_creator":"@daniel","twitter_misc":{"Written by":"Manfred Steyer, GDE","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/"},"author":{"name":"Manfred Steyer, GDE","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951"},"headline":"A Lightweight And Solid Approach","datePublished":"2018-04-03T13:16:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/"},"wordCount":454,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","articleSection":["Unkategorisiert"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/","name":"A Lightweight And Solid Approach - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","datePublished":"2018-04-03T13:16:10+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","width":1280,"height":853},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/a-lightweight-and-solid-approach\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"A Lightweight And Solid Approach"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951","name":"Manfred Steyer, GDE","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","caption":"Manfred Steyer, GDE"},"sameAs":["https:\/\/x.com\/daniel"]}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/2384","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=2384"}],"version-history":[{"count":0,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/2384\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/2997"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=2384"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=2384"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=2384"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}