This Banner is For Sale !!
Get your ad here for a week in 20$ only and get upto 15k traffic Daily!!!

Real-time frontends with Kalix and Laminar

Occasions are superb to maintain techniques in sync. Right here I hold the backend and the totally different frontends (internet, cell) in sync due to occasions and Scala in all places.
Having all the pieces in sync at any time is what I name right here real-time frontends.
Occasions are broadcasted and pushed to frontends by internet sockets. Occasions are replayed with occasion sourcing in backend and frontend.

Image description
To essentially hold all the pieces in sync it is very important replay the occasions in the identical manner on each sides. For that objective, we share between backend and frontends the identical definition of occasions and the identical scala code for the replay.
This sharing not solely assist for having issues in sync but in addition to keep away from redefining the identical factor once more at frontend. Fairly often, we outline knowledge mannequin within the backend after which the identical within the totally different frontends. Right here we want to keep away from that and outline it as soon as in Kalix and reuse it within the Laminar frontends (internet, cell).
Reusing the very same scala code for the replay is de facto necessary. It saves you from out of sync issues. If in case you have totally different code (most likely additionally totally different languages) for the replay between backend and frontend, you begin shortly to have huge issues, bugs and knowledge issues. Consider a cell app you’ll want to redeploy to repair these issues (Cell deployment shouldn’t be simple).
For example my level, I’ve created a small instance. The area is crowd funding. The replay logic may be very easy and minimal but it surely’s simply an instance.
Code could be discovered right here:
The repository accommodates 3 tasks:

  • Kalix challenge
  • Laminar challenge for the net
  • Laminar + Capacitor challenge for cell app (not but out there)
    Notice: For extra info on the way to run the instance, loot on the readme of the every tasks.

Description of the instance

The app handle crowd funding tasks. A challenge has:

  • Mission ID
  • Title
  • Description
  • Aim: The sum of money you wish to obtain along with your crowd funding challenge
  • Funded: The sum of money collected to this point

You manipulate the challenge with 2 actions:

  • Change challenge particulars (Title, Description, Aim)
  • Make investments: give cash to the challenge

What’s shared ?

We share:

  • Occasions definition as protobuf
  • REST entry level arguments as protobuf
  • State (results of replay of occasions) as protobuf
  • Replay occasions logic as scala file

We merely have unix hyperlink from Kalix challenge to Laminar tasks.

Cherry-picking the shared components

Within the frontend, we’re in a distinct context and we can not simply share the entire listing of Kalix protobufs or the entire file containing the replay. We now have to isolate the components we have an interest and restructure just a little issues in Kalix by shifting what we’d like in separate information.
This denature just a little the Kalix challenge however could also be we may include a greater answer the place we share issues as they’re and discover a manner within the frontend to disregard what we do not want

Maintain all the pieces in sync

I’ve recognized 2 options:

  1. When Kalix emit an occasion it’s ship to Kafka. Every frontend register to Kafka and replay occasion acquired.
  2. A frontend emit a command to Kalix. If succesful, it despatched the associated occasion (because it additionally created in Kalix) to the server of the frontend through websocket. The frontend server broadcast it to all frontends through websocket.

The primary answer is extra elegant and work additionally with instructions issued on to Kalix (not from Frontends solely) however I select the second simply to keep away from Kafka for the second and are available up quickly with an instance.


The core of the frontend is a Laminar EventBus:

  • EventBus receives occasions and snapshots (extra about snapshot beneath) both from Kalix or from the published of occasion from different frontends.
  • From the EventBus we undergo the replay which supplies as output a Sign representing the record of all tasks. Laminar is simply excellent to do this ! as you’ll be able to see on this code:
  val $tasks: Sign[List[ProjectData]] = 
      preliminary = Record.empty[ProjectData])
      ((acc, ev) => {
        ev match {
          case evt: ProjectState =>
            replayEvent(evt.projectId, evt, true, acc, snapshotReplay)
          case evt: ProjectDetailsChanged =>
            replayEvent(evt.projectId, evt, false, acc, ProjectReplay.projectDetailsChanged)
          case evt: MoneyInvested =>
            replayEvent(evt.projectId, evt, false, acc, ProjectReplay.moneyInvested)
          case _ =>
            println("Bus no managing occasion " + ev)
Enter fullscreen mode

Exit fullscreen mode

Record of all tasks in a Laminar Sign

The construction of the tasks within the record which is maintained within the Sign is twofold:

  • The state
  • The record of occasions

The state is at all times current however the record of occasions is elective.
Once we fetch knowledge from kalix, we’ve 2 use circumstances which has been chosen for efficiency purpose:

  1. Once we show the record of all tasks (AppProjectsPage), we fetch an inventory of state which is taken into account as a snapshot within the replay of occasions. Why ? as a result of it might be too expensive to fetch all occasions of all tasks and replay all these occasions. I that case every challenge construction accommodates solely the state, not the occasions half.
  2. Once we have a look at one challenge (within the Mission Dashboard web page), we fetch all occasions of the challenge and replay them. Right here the challenge construction comprise the state and the occasions.

It’s possible you’ll ask: Why wouldn’t it be attention-grabbing to have the record of occasions in a primary place? As a result of you’ll be able to show it to the consumer because the historical past of the challenge.

This was for knowledge fetched from the backend however what occur when an occasion is acquired from one other frontend ? We replace the state utilizing the replay logic and we add the occasion to the record of occasions within the challenge construction.


Laminar is de facto serving to to stream occasions throughout frontends and inside frontends and actually enable to have simply all frontends in sync.
This answer ought to prevent improvement time and make the synchronisation between backend and frontends extra dependable.
There are various areas of enhancements:

  • Issues could be extra sophisticated for those who can not take all of your knowledge within the frontend.
  • In an even bigger utility, with a number of entity, you’ll want to segregate your occasions.
  • Learn how to handle unreceived occasions ? Consumer can at all times refresh the web page to get contemporary knowledge however that isn’t actually an answer and cell app might hold state in an extended run.

Do not hesitate to present me your feedbacks to:

The Article was Inspired from tech community site.
Contact us if this is inspired from your article and we will give you credit for it for serving the community.

This Banner is For Sale !!
Get your ad here for a week in 20$ only and get upto 10k Tech related traffic daily !!!

Leave a Reply

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?