HTML over the wire / Serverside reactivity

JS frameworks like React, Vue and Svelte adds reactivity on the client side. When you update a certain text field, for example, other values reactively update based on your input. For example if you edit an element that is shown in a list, the element in the list will update automatically when edit it in the a text field.

Why can’t this also happen globally in the application? When user A looks at a list of books, and user B updates the title of on the the books, I want user A to see the change exactly when it happens. Today this type of things is pretty complicated. I want reactivity all across the application, and I’m starting this topic to discuss how we can use Kotlin to make this possible.

There has been some work in other communities to make this kind of reactivity possible, for example Hotwire (short for HTML Over The Wire) from the Ruby on Rails-community and Livewire from the Laravel/PHP community. These tools use HTTP2 and web sockets. Each view subscribes to the server and listen to updates.

I want to push things even further than the examples above, and I think that’s possible to do in a statically typed language like Kotlin: In each view, we know exactly what data that is shown. Let’s say we have a list of books:

books.forEach {
  tr { it.title }
  tr { it.numPages }
  tr { it.publisher.name }
}

We know exactly what data is needed for this view: The book’s title and numPages properties, plus the name of the publisher. When any of these updates, the subscribing web socket client, has to be updated with the new data. The server needs to keep track of what data each of its clients listen to. With static typing, this should be possible to keep track of, but we might need some extended compiler (or what to call it) for this.

We could use an ORM, like for example the entities part of the Exposed library. In the example above, a book belongs to a publisher. The models/entities would need to be extended to broadcast updates.
Example, when we update a publisher:

publisher.name = newName
publisher.save()

On save(), we save the changes to the database, but not only that: We also broadcast the update to a stream that is listened to by all the components (or whatever to call them) that are listened to by web socket clients. When a component sees an update that it needs to tell the web client about, it pushes an update of that specific data.

From the example above: If the name of the publisher of any of the books in a specific view/component is updated, this update is sent to the listening web client. We could use HTML class names to identify each element, and send JSON with data updates, with something like

{
  "changeType": "update",
  "className": "__books_id_5_publisher_name",
  "value": "The New Publisher Name"
}

An alternative is to simply use the DOM reference of whatever data we want to update. In that case we would need to keep track of DOM also on the server side (as long as a websocket client listens for updates to that view).

Then the question is: What about mobile? “We want to make JSON APIs so they can be consumed both for web and mobile”. The solution is simply to use HTML/web views for (most of) your mobile apps. To show content is the same on web as on a phone. You might need to do some mobile/platform specific things too smooth out the user experience, but 90% of the app can be based on web views (which already is the case with React Native and others). And yes, there are some exceptions to this.

So what do you think of this? Do you think the things described above could be possible? I just want to get the snow ball rolling. I don’t know about you, but I’m pretty done with microservices and HTTP calls with JSON flowing east and west. Let’s get back to rendering HTML on the server, but with the advantage of web sockets and HTTP2 so that views can be updated automatically when the data changes.

That’s definitely doable. You need some kind of “action” paradigm: an UI event generates a user intend, which is an upstream action, the server processes it and returns the event to the client, as the same downstream action with a JSON payload, to take effect on bound UI elements. But with HTTP2, Server Sent Events is also a good candidate besides WebSockets for downstream events.

1 Like

Have you seen Kweb?

2 Likes

Kweb seems great - will check it out! By the first look, it seems to do something similar to what I describe here :+1:

Kweb is awesome! Played around with it yesterday, and this is exactly what I was looking for, just without relational databases. And that’s a good thing. Relational DBs are overkill in many cases. With Shoebox observable object are stored on the disk. Will continue playing with KWeb, and hope and pray that corporate will get out of the microservices + React paradigm :pray: