How to structure the data that is sent from the server to the user?
Utilizza il schema di messaggistica . Bene, stai già utilizzando un protocollo di messaggistica, ma intendo strutturare le modifiche come messaggi ... in particolare eventi. Quando cambia il lato server, ciò si traduce in eventi aziendali. Nel tuo scenario, le tue opinioni cliente sono interessate a questi eventi. Gli eventi dovrebbero contenere tutti i dati rilevanti per quel cambiamento (non necessariamente tutti i dati della vista). La pagina del client dovrebbe quindi aggiornare le parti di vista che mantiene con i dati dell'evento.
Ad esempio, se stavi aggiornando un ticker azionario e AAPL cambiato, non dovresti spingere tutti i prezzi delle azioni verso il basso o anche tutti i dati su AAPL (nome, descrizione, ecc.). Dovresti solo spingere AAPL, il delta e il nuovo prezzo. Sul client, si aggiornerà quindi solo il prezzo delle azioni sulla vista.
Should I only send events like "this resource has been updated and you should reload it via an AJAX call" or push the updated data and replace previous data loaded via initial AJAX calls?
Direi nessuno dei due. Se stai inviando l'evento, vai avanti e invia i relativi dati (non i dati dell'intero oggetto). Dagli un nome per il tipo di evento che è. (La denominazione e i dati rilevanti per quell'evento vanno oltre l'ambito dei meccanismi meccanici del sistema. Questo ha più a che fare con il modo in cui la logica aziendale è modellata.) I tuoi updaters di vista devono sapere come tradurre ogni evento specifico in un cambio di visualizzazione preciso (cioè aggiorna solo ciò che è cambiato).
How to define a coherent and scalable skeleton to data sent? is this a model update message or "there was an error with blahblahblah" message
Direi che questa è una grande domanda a risposta aperta che dovrebbe essere suddivisa in diverse altre domande e pubblicata separatamente.
In generale, tuttavia, il tuo sistema di back-end dovrebbe creare e inviare eventi per eventi importanti alla tua attività. Questi potrebbero venire da feed esterni o da attività nel back-end stesso.
How not to send data about everything from anywhere in the backend?
Utilizza il modello di pubblicazione / sottoscrizione . Quando la tua SPA carica una nuova pagina che è interessata a ricevere aggiornamenti in tempo reale, la pagina dovrebbe iscriversi solo a quegli eventi che può utilizzare, e chiamare la logica di aggiornamento della visualizzazione al suo ingresso. Probabilmente avrai bisogno di logica pub / sub il server per ridurre il carico di rete. Esistono librerie per Websocket pub / sub, ma non sono sicuro di cosa siano nell'ecosistema Rails.
How to reduce the business logic duplication both on the server and the client side?
Sembra che tu debba aggiornare i dati della vista sia sul client che sul server. La mia ipotesi è che hai bisogno dei dati della vista lato server in modo da avere uno snapshot per avviare il client in tempo reale. Essendo che ci sono due lingue / piattaforme coinvolte (Ruby e Javascript), la logica di aggiornamento della vista dovrà essere scritta in entrambi. A parte il transpiling (che ha i suoi problemi), non vedo un modo per aggirare questo.
Punto tecnico: la manipolazione dei dati (aggiornamento della vista) non è una logica aziendale. Se intendi utilizzare la convalida dei casi, ciò sembra inevitabile poiché le convalide del cliente sono necessarie per una buona esperienza utente, ma non possono essere considerate attendibili dal server.
Ecco come vedo strutturata una cosa del genere.
Visualizzazioni client:
- Richiede un'istantanea della vista e l'ultimo numero di evento visto della vista
- Questo prepopolare la vista in modo che il client non debba creare da zero.
- Potrebbe essere su HTTP GET per semplicità
- Crea una connessione websocket e si iscrive a eventi specifici, a partire dall'ultimo numero di evento della vista.
- Riceve gli eventi su websocket e aggiorna la visualizzazione in base al tipo di evento / dati.
Comandi client:
- Richiesta di modifica dei dati (HTTP PUT / POST / DELETE)
- La risposta è solo riuscita o non riuscita + errore
- (Gli eventi generati dalla modifica arriveranno su websocket e attivano un aggiornamento della vista.)
Il lato server potrebbe essere suddiviso in più componenti con responsabilità limitate. Uno che elabora solo le richieste in arrivo e crea eventi. Un altro potrebbe gestire le sottoscrizioni dei clienti, ascoltare gli eventi (ad esempio in-process) e inoltrare gli eventi appropriati agli abbonati. Potresti avere un terzo che ascolta gli eventi e aggiorna le visualizzazioni sul lato server - forse questo accade anche prima che gli abbonati ricevano gli eventi.
Quello che ho descritto è una forma di CQRS + Messaggi e una strategia tipica per affrontare il tipo di problemi che stai affrontando.
Non ho portato Event Sourcing in questa descrizione perché non sono sicuro che sia qualcosa che vuoi prendere su o se ne hai bisogno necessariamente. Ma è un modello correlato.