52

Strangling a Monolith application with Micro Frontends using Server Side Include...

 4 years ago
source link: https://itnext.io/strangling-a-monolith-to-micro-frontends-decoupling-presentation-layer-18a33ddf591b?gi=95489c53e9da
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Strangling a Monolith application with Micro Frontends using Server Side Includes

An agile mindset promotes iteration over processes, products, and business. Nowadays evolutionary architecture is enabling incremental change in architecture over time.

The most common approaches for migrating a big monolith are:

The journey of strangling a Monolith application

Nowadays is easy to choose frameworks such as Nuxt.js and Next.js to universal render pages using React and Vue.js, also known as isomorphic applications, but it’s hard for frameworks that use their own template engines and even harder for non-javascript frameworks such as Ruby on Rails, Laravel, or Flask.

Airbnb + Hypernova as a case study

Airbnb has been steadily migrating their system built on top of Ruby on Rails moving the frontend code to a consistent architecture using Hypernova as Server-Side Rendering Service.

Image for post
Image for post
Airbnb using Hypernova as SSR Service
  • A user requests a page on the Ruby on Rails server.
  • The server gathers the necessary data to render the page.
  • The ERB template uses a custom renderer to request components to a Hypernova server.
  • Hypernova server renders all the requested components using React and sends them back to the Ruby on Rails server.
  • The components are injected in the generated page by ERB.
  • The Ruby on Rails sends back the HTML markup plus the javascript files to the browser.
  • On the browser, JavaScript is used to progressively enhance the application and make it dynamic.

Using this architecture Airbnb can reuse their React components for server-side and client-side rendering and decoupling the presentation of their Monolith built ontop Ruby on Rails.

Here a detailed article wrote by the Airbnb Engineering team.

Using Hypernova on Laravel

Laravel is a PHP web framework to build modern web applications similar to other frameworks like ASP.net MVC, Ruby on Rails and AdonisJS.

Image for post
Image for post

Laravel Application Diagram

Laraveluses Blade as the template engine for server-side rendering, and Laravel Mix to compile assets like Javascript, CSS, and Vue.js components for client-side rendering.

Supporting Vue.js on Hypernova

Airbnb Hypernova doesn’t support Vue.js out of the box but it enables us to make it developing our own Hypernova bindings, so I created hypernova-vue.

I wrote this article about how to use Vue.js with Hypernova, also you can use this generator.

1st Approach — Hypernova Client

Once the Hypernova server was configured to use Vue.js I created a custom directive in Blade in order to place hypernova components inside the Blade views.

Image for post
Image for post

Hypernova Blade Directive in AppServiceProvider.php

The Hypernova directive uses a facade which pushes the requested component into the hypernova-php client and adds a placeholder in the template view necessary to place the rendered component later.

The hypernova client is a singleton so we can persist the requested components in order to get them from the hypernova server later.

Image for post
Image for post

Hypernova Class — pushJob

Finally, Blade renders the page based on the template view and a Laravel middleware use the Facade to modify the original response. The Facade behind of scenes uses the Hypernova client to request the components to Hypernova server and replaces the placeholders with the rendered components on only one step.

Image for post
Image for post

Hypernova Middleware

I took some ideas of laravel-hypernova package but I didn’ use it because the library is not compatible with Laravel 5.8 yet and I had issues handling incoming errors from hypernova server.

Using the Hypernova directive

Laravel controller only needs to pass the view name and the data to Blade using the view function.

Image for post
Image for post

Returning a view inside the route handler

The default layout contains the HTML document and defines a NavBar component using the hypernova directive.

Image for post
Image for post

Default Layout using Blade

The welcome view uses the default layout and defines a Home component using the hypernova directive as well.

Image for post
Image for post

Welcome view

Once the HTML is rendered this is the result:

Image for post
Image for post

The page is server-side rendered and client-side dynamic using the same Vue.js components, which is pretty cool for SEO.

I enabled Laravel to universal renders Vue.js components using Hypernova server but it’s still coupled to some implementation details. Laravel needs to interact with the Hypernova server directly using the Hypernova client, so the architecture requires to develop a Hypernova client for each language or web framework.

Hypernova proxy approach

After analyzing deeply the architecture I found a common communication interface closely to the micro-frontends principles.

Image for post
Image for post

The HTML generated by Blade contains the placeholders with all the information necessary to generate a batch request to Hypernova server, even if the hypernova server fails to render the view, the client-side scripts will render the component on the browser making the Frontend resilient.

Based on the Laravel middleware approach I decided to put a Reverse Proxy between the client and the Laravel application in order to server-side include (SSI) the views coming from Hypernova server.

I gave a try to Nginx extending it using OpenResty but I found some implementation constraints using the HTML parser and HTTP Client for Lua.

Finally, after researching a lot I decided pick Go to develop it. Go has an HTTP Client and Reverse Proxy Server module out of the box and a pretty cool library to parse and mutate the DOM using query selectors.

How Hypernova proxy works

Using Hypernova proxy Laravel only needs to use the Hypernova directive in order to render the placeholders that Hypernova proxy uses to server-side include the Hypernova views in the page as we were doing before with the Laravel middleware, but now we can reuse Hypernova proxy in order to universal render views using others web frameworks.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK