[Haskell-cafe] Managing state between client/server (frontend/backend)
Alec Theriault
alec.theriault at gmail.com
Sun Jan 2 15:54:31 UTC 2022
Hi Clinton,
At the risk of being a little bit off-topic, have you considered using
Scala.js instead of GHCJS (especially since you say the backend is already
Scala)? You get the same benefits as what you describe (datatypes shared
across the client/server, fearless refactoring, etc.). We do this at work
and use the following tech stack:
- Core data types are defined in a project that is cross compiled for
JVM and JS targets (using the sbt-crossproject
<https://github.com/portable-scala/sbt-crossproject> plugin). We define
the entire schema of our REST API in this project, using endpoints4s
<https://endpoints4s.github.io/index.html> (more specifically, the
algebra project).
- The client is written in Scala.js using React. The Scala.js React
bindings we use (basically the typed API on top of React) come from
slinky <https://slinky.dev> although scalajs-react
<https://japgolly.github.io/scalajs-react/> is another popular
library for this. We derive a REST API client from the core project using
the endpoints4s xhr-client
<https://endpoints4s.github.io/interpreters/scalajs-web-xhr.html>
interpreter,
so each API call is just a function from the endpoint inputs to its
outputs. We compile all of the Scala.js code into one minified bundle which
we serve up as a resource from the backend using the SBT scalajs-bundler
<https://scalacenter.github.io/scalajs-bundler/> plugin.
- The backend exposes an Akka HTTP server, where we provide
implementations for all of the endpoints using the endpoints4s akka-http
<https://endpoints4s.github.io/interpreters/akka-http.html> interpreter
(if your backend already leverages a Scala HTTP server, there's a
good chance there's an endpoints4s interpreter for it).
The net effect is that all the project source is in Scala and the entire
build process is unified in SBT. This simplifies development quite a bit
since one SBT command will build everything and you get type errors if you
change the API without changing both the client and the server.
In any case, I'd be very interested in hearing about Haskell solutions to
this though - especially how folks handle the build system integration of
GHCJS and GHC. I believe that servant
<https://docs.servant.dev/en/stable/> fills
the niche of endpoint4s and miso <https://github.com/dmjio/miso> gets used
for building the actual client apps, although I've not used either.
Happy new year,
-Alec
On Sun, Jan 2, 2022 at 3:30 AM Clinton Mead <clintonmead at gmail.com> wrote:
> A happy new year to all the Haskell community.
>
> My current role involves an app with a Scala backend and a React/Redux
> Javascript frontend. What should be quite simple tasks are made
> difficult/impossible, firstly by the fact if you even touch a Javascript
> codebase in any significant way you break the code in weird and wonderful
> ways, which may only be apparent as random runtime errors days, weeks or
> months in the future, but another issue is that tracking some bug back from
> the browser to the backend and the database is a nightmare because it's far
> from obvious what's going on across the language boundary between Scala and
> Javascript, particularly as everything is being flattened to JSON across
> that boundary.
>
> Anyway, I was thinking of a better way of doing this, and I thought it
> would be nice if much of the code was shared between the browser frontend
> and backend server though a common datatype, with the frontend just
> compiled with GHCJS.
>
> Some of the state to the client could be readonly, and some writable. The
> actual details of pushing the data back and forth would be abstracted away
> (as much as possible). When the client does writes, it wouldn't need to
> wait for the server to process these writes, it could just save these on
> the client side state, and send them off to the server to record, but
> otherwise continue on.
>
> There's quite a few nuances here I've started to think about (and there's
> likely more I haven't thought about) and given that I don't think this idea
> is particularly novel, are there any libraries out there that already do
> roughly what I'm talking about here? If someone has already thought this
> through I don't want to reinvent the wheel.
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20220102/1c57f04e/attachment.html>
More information about the Haskell-Cafe
mailing list