Как структурировать данные, которые отправляются с сервера пользователю?
Используйте шаблон обмена сообщениями . Ну, вы уже используете протокол обмена сообщениями, но я имею в виду структурирование изменений как сообщений ... в частности, событий. Когда серверная часть изменяется, это приводит к деловым событиям. В вашем сценарии ваши клиенты заинтересованы в этих событиях. События должны содержать все данные, относящиеся к этому изменению (не обязательно все данные просмотра). Страница клиента должна затем обновить части представления, которые она поддерживает, с данными события.
Например, если вы обновляли биржевую биржу, а AAPL изменились, вам не хотелось бы сбрасывать все цены на акции или даже все данные об AAPL (имя, описание и т. Д.). Вы только подтолкнули бы AAPL, дельту и новую цену. На клиенте вы затем обновите только ту цену акций в представлении.
Должен ли я отправлять только события типа «этот ресурс обновлен, и вам следует перезагрузить его с помощью вызова AJAX» или отправить обновленные данные и заменить предыдущие данные, загруженные с помощью первоначальных вызовов AJAX?
Я бы сказал, нет. Если вы отправляете событие, продолжайте и отправьте с ним соответствующие данные (а не данные всего объекта). Дайте ему имя для такого рода событий. (Наименование и данные, относящиеся к этому событию, выходят за рамки механической работы системы. Это больше связано с моделированием бизнес-логики.) Ваши средства обновления представления должны знать, как преобразовать каждое конкретное событие в точное изменение вида (т.е. только обновление того, что изменилось).
Как определить связный и масштабируемый каркас для отправляемых данных? это сообщение об обновлении модели или сообщение об ошибке "blahblahblah"
Я бы сказал, что это большой открытый вопрос, который должен быть разбит на несколько других вопросов и размещен отдельно.
Тем не менее, в целом ваша внутренняя система должна создавать и отправлять события для важных событий в вашем бизнесе. Они могут поступать из внешних каналов или из активности самого сервера.
Как не отправлять данные обо всем откуда угодно в бэкэнд?
Используйте шаблон публикации / подписки . Когда ваш SPA загружает новую страницу, которая заинтересована в получении обновлений в реальном времени, страница должна подписываться только на те события, которые она может использовать, и вызывать логику обновления представления по мере поступления этих событий. Возможно, вам понадобится логика pub / sub на сервер для снижения нагрузки на сеть. Существуют библиотеки для публикации / публикации Websocket, но я не уверен, что это такое в экосистеме Rails.
Как уменьшить дублирование бизнес-логики как на стороне сервера, так и на стороне клиента?
Похоже, вам нужно обновить данные представления на клиенте и сервере. Я предполагаю, что вам нужны данные вида на стороне сервера, чтобы у вас был моментальный снимок, чтобы запустить клиент в реальном времени. Поскольку задействованы два языка / платформы (Ruby и Javascript), логика обновления представления должна быть записана на обоих языках. Помимо транспаранта (у которого есть свои проблемы), я не вижу способа обойти это.
Технический момент: манипулирование данными (просмотр обновлений) не является бизнес-логикой. Если вы имеете в виду проверку варианта использования, то это кажется неизбежным, поскольку проверки клиента необходимы для хорошего пользовательского опыта, но в конечном итоге не могут быть доверены серверу.
Вот как я вижу такую вещь, хорошо структурированную.
Просмотры клиента:
- Запрашивает снимок представления и последний увиденный номер события представления
- Это позволит предварительно заполнить представление, чтобы клиенту не приходилось строить с нуля.
- Может быть через HTTP GET для простоты
- Создает соединение через веб-сокет и подписывается на определенные события, начиная с номера последнего события представления.
- Получает события через веб-сокет и обновляет его представление в зависимости от типа события / данных.
Клиентские команды:
- Запросить изменение данных (HTTP PUT / POST / DELETE)
- Ответ только успех или неудача + ошибка
- (События, сгенерированные изменением, будут проходить через веб-сокет и запускать обновление представления.)
На самом деле серверная сторона может быть разбита на несколько компонентов с ограниченной ответственностью. Тот, который просто обрабатывает входящие запросы и создает события. Другой может управлять подписками клиентов, прослушивать события (скажем, в процессе) и пересылать соответствующие события подписчикам. У вас может быть третий, который прослушивает события и обновляет представления на стороне сервера - возможно, это происходит даже до того, как подписчики получают события.
Я описал форму CQRS + Messaging и типичную стратегию для решения проблем, с которыми вы сталкиваетесь.
Я не включил Event Sourcing в это описание, так как не уверен, что это то, что вы хотите взять на себя, или вам это нужно обязательно. Но это связанный шаблон.