Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping Client State Up-To-Date In Reagent / Clojurescript

I am not sure on the best way to go about this:

I have a web application I am writing which implements basic CRUD functionality for a number of "Project" objects. So, a user can create his/her own set of Projects.

I have written a REST API for adding / removing / listing the projects, and I have written a Reagent front-end client. The client's projects are held in a reagent atom (ratom), as you would expect.

This is where it gets interesting.

In all the tutorials I have seen, it shows you how to update the ratom and your GUI will update automatically. I have that, that works.

What I am currently doing is, at the point of updating the client state, I make my REST POST call to update the server state on the database.

But, this doesn't feel right. I am now storing state in two places: on the client and on the server, and both could be different.

If I were implementing this as a plain old web page, the server would send a page back to the client with the latest state of the database in it. But, state already exists on the client in the ratom, and I don't know how I should synchronise it.

Should I make another call to the server (a GET request) after the initial POST is successful? This could replace the contents of the ratom. Then I'm making two requests.. which seems wasteful.

Or is the best practice to use something like chord or sente to manage the client state asynchronously. This would be better, as it would mean changes from other users would be instantaneously refreshed on the client side. But, I can't see any tutorials demonstrating react with either of these so maybe I am on the wrong track.

So the question is simply, how should one combine react with REST?

thanks

like image 469
Rob Moffat Avatar asked Nov 26 '14 22:11

Rob Moffat


2 Answers

I agree with @myguidingstar that your problem is more about client-server synchronization than about clojure or reagent. You could have a similar problem, say, with GWT (been there, ...)

Should I make another call to the server (a GET request) after the initial POST is successful? This could replace the contents of the ratom. Then I'm making two requests.. which seems wasteful.

You seem to miss that POST requests can also trigger responses from the server.

The big question here is why do you need the DB state on the client? Do you have requirements which force you to minimize the amount of GET requests to fetch data from the server? Or do you have business logic implemented on the client (ClojureScript/reagent) side that just doesn't need server interaction? You need to consider also the other side of the same issue: Is it okay if your client state doesn't get updated in a while or could you run into consistency issues because "something else" is modifying the data on the server behind your client's back?

Finally, you say that you

.. don't know how I should synchronise it.

What exactly are your issues? Why not just update the app-state (swap! app-state update-in ...) after you've fetched the data from the server, as described in the reagent-tutorial?

like image 135
schaueho Avatar answered Sep 25 '22 04:09

schaueho


This is a big question about client-server synchronization that most web apps struggle with.

There's a library by Tonsky for the very problem:

https://github.com/tonsky/datascript

Read his blog post and the example datascript-chat to understand the design. This will require a lot to learn, but I'm afraid it's the only way that is not kind of "doesn't feel right".

like image 30
myguidingstar Avatar answered Sep 22 '22 04:09

myguidingstar