Front-end microservices with Web Components

Written by kobvel | Published 2017/10/25
Tech Story Tags: web-development | microservices | web-components | frontend-microservices | software-development

TLDRvia the TL;DR App

Why microservices?

That could be a sign for you, when you have a big enterprise application where you can easily divide logic by domain accessory. There’re a bunch of apps in Google nowadays e.g. _Google Driv_e, Google Docs, Gmail etc and it’s quite obvious that Google Drive and Google Docs should not be a single app just because both use authentication and same frameworks.

Your case might not be so obvious as Google’s one but let me describe some Benefits of front-end microservices architecture:

  • Maintainability. You can easily divide your resources into different teams which will grow their knowledge in particular domain related to some part of the application.
  • Technologies freedom. If you like to try VueJS or another new technology, go ahead! Not much risk, you just start one single microservice instead of rewriting everything.
  • Independent Deployment. It gives so much freedom when you can release small pieces of the application. Fixes and releases go more smoothly.

Of course, it goes with some Costs:

  • Maintaining consistency. You need to invest time to make your apps work together. I found more bugs once I’ve rewritten application to microservices model, which were invisible while the application was a monolith.
  • Operational Complexity. All magic with regular deploys must work like a charm, otherwise, you will get more pains than benefits.

Approach

I did a research. And even asked the community for any existing examples:

P.S. I was looking for any solutions besides iFrame.

I have successfully built Polymer with AngularJS as a nested component. But, somewhere on forums, there was a restriction about doing that. So I decided to go lower level and built the same approach on the level of Web Components.

Web Components solution

Solution relies deeply on the single feature from Web Components standard. HTML Imports: a way to include and reuse HTML documents via other HTML documents (spec, tutorial).

Idea is to predefine components as HTML imports, while each of them could include their own scripts and styles. So we can decide on the top level which HTML import should be presented in DOM at the moment, and rest of things should be handled by the imported document itself.

HTML imports driven microservices

Shell — is a top level wrapper which consists of component picker and container for components. Also should include views or controllers which allow user manipulating components.

Container — the actual root place where HTML of nested application should be injected. (It should have a single entry point for all nested apps).

Component picker —service which allows managing nested application which is active at the moment.

HTML imports — our abstract microservices. Could be whole apps written in different frameworks.

Base example of implementation

Here is a full repo of Web Components driven microservices with nested AngularJS and React applications. Many thanks to Andrew Dacenko for the support on the early phase!

index.html

16 LOC: Container for nested applications.

Two nested applications — angular-app.html and react-app.html. By clicking on one of two buttons we load corresponding application with the help of loader.js.

loader.js

loader.js is a kind of Component picker which I’ve described in the previous paragraph.

Conclusion

This approach was implemented for a production application. It was proven by thousands of users.

I would suggest to answer yourself few questions before you start dividing your application to front-end microservices:

  • How big is your application in terms of team and code?
  • Can you divide your app into small pieces by domain accessory?
  • How easy can you release small features for your application?

If you want to get an info straight from the horse’s mouth follow me on Twitter and Medium account.


Published by HackerNoon on 2017/10/25