¿Cómo estructurar los datos que se envían desde el servidor al usuario?
Usa el patrón de mensajes . Bueno, ya estás usando un protocolo de mensajería, pero quiero decir estructurar los cambios como mensajes ... específicamente eventos. Cuando el lado del servidor cambia, eso resulta en eventos de negocios. En su escenario, las opiniones de sus clientes están interesadas en estos eventos. Los eventos deben contener todos los datos relevantes para ese cambio (no necesariamente todos los datos de vista). La página del cliente debería actualizar las partes de la vista que mantiene con los datos del evento.
Por ejemplo, si estaba actualizando un ticker de acciones y AAPL cambió, no querría bajar todos los precios de las acciones o incluso todos los datos sobre AAPL (nombre, descripción, etc.). Solo presionaría AAPL, el delta y el nuevo precio. En el cliente, solo actualizaría ese precio de la acción en la vista.
¿Debería enviar solo eventos como "este recurso ha sido actualizado y usted debería volver a cargarlo a través de una llamada AJAX" o enviar los datos actualizados y reemplazar los datos anteriores cargados a través de llamadas AJAX iniciales?
Yo diría que ninguno. Si está enviando el evento, continúe y envíe datos relevantes (no todos los datos del objeto). Déle un nombre al tipo de evento que es. (Los nombres y los datos relevantes para ese evento están más allá del alcance del funcionamiento mecánico del sistema. Esto tiene más que ver con la forma en que se modela la lógica de negocios). Los actualizadores de su vista necesitan saber cómo traducir cada evento específico en un cambio de vista preciso (es decir, solo actualizar lo que ha cambiado).
¿Cómo definir un esqueleto coherente y escalable para los datos enviados? ¿Es este un mensaje de actualización del modelo o el mensaje "hubo un error con blahblahblah"?
Yo diría que esta es una pregunta grande y abierta que debería dividirse en varias otras preguntas y publicarse por separado.
Sin embargo, en general, su sistema de back-end debería crear y enviar eventos para eventos importantes para su negocio. Esos pueden provenir de fuentes externas o de actividad en el back-end.
¿Cómo no enviar datos sobre todo desde cualquier lugar del backend?
Use el patrón de publicación / suscripción . Cuando su SPA carga una nueva página que está interesada en recibir actualizaciones en tiempo real, la página debe suscribirse solo a los eventos que puede usar, y llamar a la lógica de actualización de vista a medida que ingresan esos eventos. Probablemente necesitará lógica de pub / sub en el servidor para reducir la carga de la red. Existen bibliotecas para Websocket pub / sub, pero no estoy seguro de cuáles están en el ecosistema de Rails.
¿Cómo reducir la duplicación de lógica de negocios tanto en el servidor como en el lado del cliente?
Parece que tiene que actualizar los datos de vista tanto en el cliente como en el servidor. Supongo que necesita los datos de vista del lado del servidor para tener una instantánea para iniciar el cliente en tiempo real. Dado que hay dos idiomas / plataformas involucrados (Ruby y Javascript), la lógica de actualización de la vista deberá escribirse en ambos. Además de transpirar (que tiene sus propios problemas), no veo una forma de evitarlo.
Punto técnico: la manipulación de datos (ver actualización) no es lógica empresarial. Si se refiere a la validación de casos de uso, eso parece inevitable ya que las validaciones del cliente son necesarias para una buena experiencia del usuario, pero en última instancia el servidor no puede confiar en él.
Así es como veo que tal cosa está bien estructurada.
Vistas del cliente:
- Solicita una instantánea de vista y el último número de evento visto de la vista
- Esto prepoblará la vista para que el cliente no tenga que construir desde cero.
- Podría estar sobre HTTP GET para simplificar
- Establece una conexión websocket y se suscribe a eventos específicos, a partir del último número de evento de la vista.
- Recibe eventos a través de websocket y actualiza su vista según el tipo de evento / datos.
Comandos del cliente:
- Solicitar cambio de datos (HTTP PUT / POST / DELETE)
- La respuesta es solo éxito o falla + error
- (Los eventos generados por el cambio vendrán a través de websocket y desencadenarán una actualización de vista).
El lado del servidor podría dividirse en varios componentes con responsabilidades limitadas. Uno que solo procesa las solicitudes entrantes y crea eventos. Otro podría administrar suscripciones de clientes, escuchar eventos (por ejemplo, en proceso) y enviar eventos apropiados a los suscriptores. Podría tener un tercero que escuche eventos y actualice las vistas del lado del servidor; tal vez esto incluso ocurra antes de que los suscriptores reciban los eventos.
Lo que he descrito es una forma de mensajería CQRS + , y una estrategia típica para abordar el tipo de problemas que enfrenta.
No incluí Event Sourcing en esta descripción, ya que no estoy seguro de si es algo que desea asumir o si lo necesita necesariamente. Pero es un patrón relacionado.