Recommended practices for Server <-> Browser data transfer.
I think we should have some.
The current common approach is to hydrate the data into a serializable format (eg json) then deserialize on the client, these way a whole structure can be moved from server to client.
I think you should have a look at what David Nolan is doing with Om Next in ClojureScript.
Thanks for the tips @bep, I'll take a look. This also relates to how we might do #23 I think. A lot to think about here.
I've done a proof-of-concept of net/rpc over websockets in trakting. It mirrors the database interface to the rpc clients, with some minimal code gen it should be quite pleasant.
That approach still feels a little like 90s coding though and I think there should be something more flux-like.
I'd second net/rpc over websockets. Works like a dream.
i am propose :
Delta updates using JSONPatch (RFC6902) Supports Server-Sent Events (EventSource) and WebSockets SSE client-side poly-fill to fallback to long-polling in older browsers (IE8+).
From the GO side its just a matter of keeping a struct in memory, and any changes will be in the JSON client side. Its very very simple to use. The idea if to just let the front end do the same. The js binds to the JSON and also listens for changes. Its turlts all the way down basically and lends itself to functional transforms client side too.
Why not use encoding/gob for data transfer?
The payloads will be smaller, faster to parse. We don't need it to be humanly readable since the Go structs will be shared between the client and the server.
It's already the default encoding used when implementing a net/rpc over websocket.
Why not use encoding/gob for data transfer?
Or ... https://github.com/Sereal/Sereal/tree/master/Go/sereal
Proper handling of object references (including circular refs) and with both JS and Go implementations.
Quick brain-dump on the strategy I've been leaning towards.
@glorieux wrote:
Why not use encoding/gob for data transfer?
I've been using pdf/websocketrwc as a thin wrapper to gorilla/websocket (since the core websocket implementation has a number of well-known issues) connections on the server-side, and a GopherJS websocket on the client-side, as underlying connections for net/rpc which uses gob under the hood.
Using zhuyie/bidirpc or similar as a net/rpc wrapper provides bi-directional RPC, which allows server-initiated actions on the client, that I drop into the same redux-style dispatcher that I'm using for local state updates. But straight net/rpc over websocket works fine for uni-directional comms.
The way I approach this is have write operations via RPC, and having a streaming connection open that receives relevant state diffs. In my case this is over the same RPC mechanism, but it doesn't have to be. Serialization format is not that important, they are nearly all interchangeable.
Lots of ways to do this. Really depends on your backend and requirements. Maybe implementation details aren't what best practices should be about.
So there are lots of good options for client/server data transfer, the main problem with this as I see it, is:
- However you choose to transport the data to/from your Go code and the server, you also need to transport these data to/from the Go and JS side
- With that I see 1) A "double serialization penalty" and 2) Rather complex and not very pretty solutions (JSON encoding/decoding from/to Go structs).