/server (ocaml), /client (js_of_ocaml), /shared interop

I’m 99% sure this is possible, but I think setting t up is error prone, and am wondering if anyone know of existing projects that do this that I can learn from.

I would like to setup a simple webapp where we have:

proj/server/ ... (dune project, ocaml)
proj/client/ ... (dune project, js_of_ocaml)
proj/shared/ ... (dune project, just some shared types)

here proj/server depends on proj/shared
proj/client depends on poj/shared

then, I want to do some magic involving json so that:

  1. proj/client (running in browser) can take a construct a type in proj/shared
  2. we take this obj x (in browser), convert it to json, HTTP post it to proj/server
  3. proj/server (running ocaml on x86_64) takes the json, de-serializes it to relevant type in proj/shared
  4. proj/server (running ocaml on x86_64) constructs a value y from proj/server, then encodes y into json
  5. proj/server (running ocaml on x86_64) sends back json in reponse to POST
  6. proj/client (running in browser) takes the json, and deserializes it to y

The XY problem here is: we should get type safe http get/post/websockets, as long as we only use types in proj/shared, and we do some json deriving magic

Any advice for projects / sample code to look for? (I’m mainly looking for advice in the form of sample code / projects to look for; I already agree this is possible in theory.)

This is exactly what is happening in the fullstack jsoo example in the Dream examples I think (minus the deriving JSON). Note that you’ll probably incur a bit of a performance hit by using OCaml JSON parsers in the browser rather than the built-in browser API for it.

2 Likes

If you are going to use js_of_ocaml in the frontend, you could look into Ocsigen, which is a fullstack solution which seamlessly integrates backend and frontend into a single codebase for both web and mobile targets. From the page:

Multi-tier programming: client and server sides of the application are written using the same language, and as a single code. Annotations in the code are used indicate on which side the code is to be run. The client side parts are automatically extracted and compiled into JavaScript to be executed in the browser. This gives a lot of flexibility to the programmer, allowing for example to generate some parts of pages either on client or server code according to your needs. It also makes communication between server and client straightforward, as you can use server side variables in client code, or call a server side OCaml functions from client code.

Unless you’re dead set on piping everything through a websocket, you may also find interest in the following package:

Sharing routes safely between the client and server becomes possible, a potentially pretty powerful option IMO.

I’m learning OCaml myself, and this package definitely piqued my interest.

1 Like

(I can anecdotally confirm that the 3 directory structure works great :slight_smile: ) But I want to bounce on @yawaramin recommendation by linking the Eliom PPX syntax extension webpage which clearly highlights why Ocsigen is the undisputed king of smooth client/server interaction! (also check their real tutorials, this is just a teaser)

(In case you can’t use Ocsigen, I liked their stuff so much that I stole their idea of interleaving client/server code in ppx_shared, but this is a dirt cheap hack and you’ll still have to handle the hard parts of client/server communication yourself)

1 Like