Где и какие ресурсы?
REST - это все, что касается адресации ресурсов без сохранения состояния и обнаружения. Он не должен быть реализован через HTTP, и при этом он не должен полагаться на JSON или XML, хотя настоятельно рекомендуется использовать формат данных гипермедиа (см. Принцип HATEOAS ), поскольку желательны ссылки и идентификаторы.
Итак, возникает вопрос: как можно думать о синхронизации с точки зрения ресурсов?
Что такое двунаправленная синхронизация? **
Двунаправленная синхронизация - это процесс обновления ресурсов, представленных на графе узлов, чтобы в конце процесса все узлы обновили свои ресурсы в соответствии с правилами, регулирующими эти ресурсы. Обычно подразумевается, что все узлы будут иметь самую последнюю версию ресурсов, представленную в графе. В простейшем случае граф состоит из двух узлов: локального и удаленного. Local инициирует синхронизацию.
Таким образом, ключевым ресурсом, к которому необходимо обратиться, является журнал транзакций, и поэтому процесс синхронизации может выглядеть следующим образом для коллекции «items» в HTTP:
Шаг 1 - Локальный извлекает журнал транзакций
Местный: GET /remotehost/items/transactions?earliest=2000-01-01T12:34:56.789Z
Удаленный: 200 ОК с телом, содержащим журнал транзакций, содержащий поля, подобные этим.
itemId
- UUID для предоставления общего первичного ключа
updatedAt
- отметка времени для предоставления координированной точки, когда данные были в последний раз обновлены (при условии, что история изменений не требуется)
fingerprint
- SHA1-хэш содержимого данных для быстрого сравнения, если updateAt
прошло несколько секунд
itemURI
- полный URI для элемента, чтобы разрешить поиск позже
Шаг 2 - Local сравнивает удаленный журнал транзакций с его собственным
Это применение бизнес-правил о том, как синхронизировать. Как правило, itemId
идентифицируют локальный ресурс, затем сравнивают отпечаток пальца. Если есть разница, то сравнениеupdatedAt
. Если они слишком близки для вызова, то нужно будет принять решение о том, чтобы выполнить извлечение на основе другого узла (возможно, это более важно), или переместить на другой узел (этот узел более важен). Если удаленный ресурс отсутствует локально, то делается push-запись (она содержит фактические данные для вставки / обновления). Предполагается, что любые локальные ресурсы, отсутствующие в журнале удаленных транзакций, не изменились.
Запросы извлечения выполняются для удаленного узла, так что данные существуют локально с использованием itemURI
. Они не применяются локально, пока позже.
Шаг 3. Передайте локальный журнал транзакций синхронизации на удаленный
Local: PUT /remotehost/items/transactions
с телом, содержащим локальный журнал транзакций синхронизации.
Удаленный узел может обрабатывать это синхронно (если он маленький и быстрый) или асинхронно (например, 202 ПРИНЯТО ), если он может вызвать большие накладные расходы. Если предположить синхронную операцию, то результатом будет либо 200 OK, либо 409 CONFLICT в зависимости от успеха или неудачи. В случае КОНФЛИКТА 409 , процесс должен быть запущен снова, поскольку на удаленном узле произошел сбой оптимистической блокировки (кто-то изменил данные во время синхронизации). Удаленные обновления обрабатываются в соответствии с собственной транзакцией приложения.
Шаг 4 - Обновление локально
Данные, полученные на шаге 2, применяются локально в рамках транзакции приложения.
Хотя вышеприведенное не является совершенным (есть несколько ситуаций, когда локальные и удаленные могут столкнуться с проблемами, а удаленное извлечение данных из локальных систем, вероятно, более эффективно, чем вставка их в большое PUT), оно демонстрирует, как можно использовать REST во время направленный процесс синхронизации.