<div dir="ltr"><div>Hi Clinton,</div><div><br></div><div>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:</div><div><ul><li>Core data types are defined in a project that is cross compiled for JVM and JS targets (using the <a href="https://github.com/portable-scala/sbt-crossproject">sbt-crossproject</a> plugin). We define the entire schema of our REST API in this project, using <a href="https://endpoints4s.github.io/index.html">endpoints4s</a> (more specifically, the algebra project).</li><li>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 <a href="https://slinky.dev">slinky</a> although <a href="https://japgolly.github.io/scalajs-react/">scalajs-react</a> is another popular library for this. We derive a REST API client from the core project using the <a href="https://endpoints4s.github.io/interpreters/scalajs-web-xhr.html">endpoints4s xhr-client</a> 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 <a href="https://scalacenter.github.io/scalajs-bundler/">scalajs-bundler</a> plugin.</li><li>The backend exposes an Akka HTTP server, where we provide implementations for all of the endpoints using the <a href="https://endpoints4s.github.io/interpreters/akka-http.html">endpoints4s akka-http</a> interpreter (if your backend already leverages a Scala HTTP server, there's a good chance there's an endpoints4s interpreter for it).</li></ul><div>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.</div><div><br></div><div>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 <a href="https://docs.servant.dev/en/stable/">servant</a> fills the niche of endpoint4s and <a href="https://github.com/dmjio/miso">miso</a> gets used for building the actual client apps, although I've not used either.</div><div><br></div><div>Happy new year,</div><div><br></div><div>-Alec</div><div><br></div></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Jan 2, 2022 at 3:30 AM Clinton Mead <<a href="mailto:clintonmead@gmail.com">clintonmead@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">A happy new year to all the Haskell community.<div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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. </div><div><br></div><div>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.</div></div>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div></div>