Come strutturare i dati inviati dal server all'utente?
Usa il modello di messaggistica . Bene, stai già utilizzando un protocollo di messaggistica, ma intendo strutturare le modifiche come messaggi ... in particolare eventi. Quando il lato server cambia, ciò si traduce in eventi aziendali. Nel tuo scenario, le visualizzazioni dei tuoi clienti sono interessate a questi eventi. Gli eventi dovrebbero contenere tutti i dati rilevanti per quella modifica (non necessariamente tutti i dati di visualizzazione). La pagina client dovrebbe quindi aggiornare le parti della vista che mantiene con i dati dell'evento.
Ad esempio, se stavi aggiornando un ticker azionario e AAPL fosse cambiato, non vorrai abbassare tutti i prezzi delle azioni o anche tutti i dati su AAPL (nome, descrizione, ecc.). Spingeresti solo AAPL, il delta e il nuovo prezzo. Sul client, si aggiornerà quindi solo quel prezzo azionario nella vista.
Devo solo inviare eventi come "questa risorsa è stata aggiornata e è necessario ricaricarla tramite una chiamata AJAX" o inviare i dati aggiornati e sostituire i dati precedenti caricati tramite le chiamate AJAX iniziali?
Non direi nessuno dei due. Se stai inviando l'evento, vai avanti e invia con te i dati pertinenti (non i dati dell'intero oggetto). Dagli un nome per il tipo di evento che è. (La denominazione e quali dati sono rilevanti per quell'evento va oltre lo scopo delle lavorazioni meccaniche del sistema. Ciò ha più a che fare con il modo in cui viene modellata la logica aziendale.) I programmi di aggiornamento della vista devono sapere come tradurre ogni evento specifico in una modifica precisa della vista (ovvero aggiorna solo ciò che è cambiato).
Come definire uno scheletro coerente e scalabile per i dati inviati? è questo un messaggio di aggiornamento del modello o "si è verificato un errore con blahblahblah"
Direi che questa è una grande domanda a risposta aperta che dovrebbe essere suddivisa in molte altre domande e pubblicata separatamente.
In generale, tuttavia, il sistema di back-end dovrebbe creare e inviare eventi per eventi importanti per l'azienda. Questi potrebbero provenire da feed esterni o da attività nel back-end stesso.
Come non inviare dati su tutto da qualsiasi parte del back-end?
Usa il modello di pubblicazione / iscrizione . Quando la SPA carica una nuova pagina che è interessata a ricevere aggiornamenti in tempo reale, la pagina dovrebbe iscriversi solo agli eventi che può utilizzare e chiamare la logica di aggiornamento della vista man mano che tali eventi entrano. Probabilmente avrai bisogno della 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.
Come ridurre la duplicazione della logica aziendale sia sul lato server che sul lato client?
Sembra che tu debba aggiornare i dati di visualizzazione sia sul client che sul server. Suppongo che siano necessari i dati di visualizzazione sul lato server in modo da disporre di un'istantanea per avviare il client in tempo reale. Dato che ci sono due lingue / piattaforme coinvolte (Ruby e Javascript), la logica di aggiornamento della vista dovrà essere scritta in entrambe. A parte la traspilazione (che ha i suoi problemi), non vedo un modo per aggirare questo.
Punto tecnico: la manipolazione dei dati (visualizza aggiornamento) non è una logica aziendale. Se si intende la convalida del caso d'uso, ciò sembra inevitabile poiché le convalide del client sono necessarie per una buona esperienza utente, ma alla fine non possono essere ritenute affidabili dal server.
Ecco come vedo una cosa del genere strutturata bene.
Visualizzazioni client:
- Richiede un'istantanea della vista e il numero dell'ultimo evento visto della vista
- Questo prepopolerà la vista in modo che il client non debba costruire da zero.
- Potrebbe essere su HTTP GET per semplicità
- Stabilisce una connessione al websocket e si iscrive a eventi specifici, a partire dall'ultimo numero dell'evento della vista.
- Riceve eventi tramite websocket e aggiorna la sua vista in base al tipo / ai dati dell'evento.
Comandi del cliente:
- Richiedi modifica dati (HTTP PUT / POST / DELETE)
- La risposta è solo successo o fallimento + errore
- (Gli eventi generati dalla modifica verranno inseriti nel websocket e genereranno un aggiornamento della vista.)
Il lato server potrebbe effettivamente essere suddiviso in più componenti con responsabilità limitate. Uno che elabora solo le richieste in arrivo e crea eventi. Un altro potrebbe gestire gli abbonamenti dei clienti, ascoltare gli eventi (diciamo in-process) e inoltrare gli eventi appropriati agli abbonati. Potresti avere un terzo che ascolta gli eventi e aggiorna le visualizzazioni lato server, forse ciò 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 inserito Event Sourcing in questa descrizione in quanto non sono sicuro se si tratti di qualcosa che si desidera affrontare o se è necessario. Ma è un modello correlato.