Подход RESTful к синхронизации данных

Предположим, что следующий сценарий. Веб-приложение обслуживает ресурсы через RESTful API. Ряд клиентов использует этот API. Цель состоит в том, чтобы данные на клиентах синхронизировались с веб-приложением (в обоих направлениях).

Самый простой способ сделать это - спросить API, если какой-либо из ресурсов изменился с момента последнего синхронизации клиента с API. Это означает, что клиенту необходимо запросить API для соответствующих ресурсов, сопровождаемых меткой времени (чтобы проверить, нужно ли обновлять данные). Это кажется мне похожим на подход с наименьшими затратами с точки зрения ненужного потребления полосы пропускания.

Однако я чувствую, что этот подход имеет несколько недостатков в плане дизайна и ответственности. Например, API не должен иметь дело с проверкой того, устарели ли ресурсы. Похоже, что единственная ответственность API должна заключаться в том, чтобы обслуживать ресурсы, когда их спрашивали, без необходимости иметь дело с аспектом обновления. Следуя этому второму подходу, клиент будет запрашивать много данных каждый раз, когда он захочет обновить свои данные, чтобы синхронизировать его с веб-приложением. Другими словами, клиент проверяет, являются ли данные, которые он получил, новее, чем локально сохраненные данные. Если этот процесс происходит каждые несколько минут, это может стать значительным бременем для системы.

Я вижу это правильно или есть средняя дорога, которую я пропускаю?

Ответ 1

Это довольно распространенная проблема, и подход RESTful может помочь вам решить ее. HTTP (протокол приложения, обычно используемый для создания сервисов RESTful) поддерживает различные методы, которые можно использовать для синхронизации клиентов API с данными на стороне сервера.

Если клиент получает заголовок Last-Modified или E-Tag в ответе HTTP, он может использовать эту информацию для выполнения условных вызовов GET в будущем. Это позволяет серверу быстро указать с помощью ответа 304 – Not Modified что ранее сохраненное представление клиента по-прежнему является действительным и точным. Это позволит серверу (или, что еще лучше, промежуточному прокси-серверу или серверу кэширования) быть настолько эффективным, насколько это возможно, в том, как он отвечает на запросы клиентов, потенциально уменьшая дорогостоящие обратные обращения к внутреннему хранилищу данных.

Если ответ содержит заголовок Last-Modified и клиент желает воспользоваться преимуществами оптимизации производительности, доступной с ним, он должен включить директиву If-Modified-Since в последующем вызове GET для того же URI, передавая то же значение метки времени это получил. Это указывает серверу только ПОЛУЧИТЬ информацию из авторитетного внутреннего источника, если он знает, что она изменилась с того времени. Конечно, ваш сервер должен быть создан для поддержки этой техники.

Аналогичный принцип применяется к заголовкам E-Tag. E-Tag - это простой хеш-код, представляющий конкретное состояние ресурса в определенный момент времени. Если ресурс изменяется каким-либо образом, изменяется и значение E-Tag. Если клиент видит E-Tag в ответе, он должен передать его в последующих запросах GET на тот же URI, что позволяет серверу быстро определить, имеется ли у клиента актуальное представление ресурса.

Наконец, вам, вероятно, следует взглянуть на метод длинных опросов, чтобы уменьшить количество повторных запросов GET, отправляемых вашими клиентами на сервер. По сути, хитрость заключается в том, чтобы выдавать очень длинные запросы GET серверу, чтобы отслеживать изменения данных на сервере. GET не вернет ответ до тех пор, пока не будут изменены данные или не истечет очень длительное время ожидания. Если последнее, клиент просто повторно выдает тот же долгоживущий запрос, чтобы снова отслеживать изменения. Смотрите также такие темы, как Comet и Web Sockets, которые похожи по подходу.

Ответ 2

Я также использую метку времени и использовал для получения статуса строки в ответе, чтобы клиент мог выполнить создание, обновление или удаление.

Моя проблема в этом случае: Supousse я запрашиваю изменения каждые 5 минут. - на минуте 2 ресурс был создан - на минуте 4 ресурс был обновлен - на минуте 5 я буду запрашивать измененные данные и получаю ресурс с актуальным статусом строки "обновлен". Проблема в том, что клиент попытается выполнить обновление без предварительного создания.

Есть идеи?