Как реализовать сложные условные массовые частичные обновления через JSON API? - PullRequest
0 голосов
/ 27 сентября 2018

В протоколе HTTP есть частичные обновления POST и PATCH методов.В методе PATCH для JSON API есть RFC 5789 , RFC 6902 , RFC 7396 .

Но у меня есть конкретный вопроск большим ресурсам, которые должны быть частично обновлены с довольно сложными условиями.

Допустим, у нас есть конечный элемент API "/members", который напоминает большую коллекцию с тысячами записей, где каждая запись имеет десятки полей.Таким образом, клиенты частично читают эти значения с помощью метода "GET /members?fields=f1,f2,f3" с разбивкой на страницы, и каждый клиент читает только подмножество полей, необходимых для их текущей задачи.

Чтобы упростить вопрос, давайте предположим, что в каждой записи есть одна обязательная "email" поле для идентификации и несколько необязательных полей.

{
"email": "user@organization.com",
"optional1": "x",
"optional2": "x",
"optional3": "x"
}

И у нас есть два клиента, работающих параллельно для создания и обновления новых записей оптом.Но каждый клиент желает перезаписать только свое подмножество необязательных полей.

Таким образом, клиент A отправит запрос со значениями A для массового исправления, которому будет разрешено перезаписать значение поля "optional1" только потому, чтоэто поле важно для их задачи.И этот клиент также будет указывать значение для поля "optional2" для новых записей.И этот клиент вообще не указал поле "optional3".

{
"email": "user@organization.com",
"optional1": "A",
"optional2": "A"
}

Хотя эта запись новая, она полностью записывается в хранилище.Затем клиент B будет отправлять запрос со значениями B для массового исправления, для которого будет разрешено перезаписывать значение поля "optional2" только потому, что это поле необходимо для их задачи.

{
"email": "user@organization.com",
"optional1": "B",
"optional2": "B",
"optional3": "B"
}

Поскольку записьуже существует, поле "optional1" этой записи должно остаться с тем же старым значением A, поскольку это поле не является обязательным, значение поля "optional2" должно быть перезаписано новым значением B, поскольку это поле является обязательным,и значение поля "optional3" должно получить значение B, потому что это поле было просто пустым.Объединенный результат действий должен быть следующим:

{
"email": "user@organization.com",
"optional1": "A",
"optional2": "B",
"optional3": "B"
}

Таким образом, поведение зависит от существования записи.Как вы, ребята, реализовали бы этот метод многократного использования конечной точки в JSON API для параллельных параллельных частичных обновлений таких коллекций со сложными условиями, которые позволили бы клиентам этого API перезаписывать только подмножество полей в записи, если эта запись уже существует и содержит некоторые значения?

Решение RFC 6902 не совпадает, поскольку обе операции add и replace фактически заменяют значение.

add - если в целевом местоположении указан элемент объекта, который существует, значение этого элемента заменяется.

replace - Операция «replace» заменяет значение в целевом местоположении новымзначение.Объект операции ДОЛЖЕН содержать элемент «value», содержимое которого указывает значение замены.

Вы можете увидеть, как это соответствует методу Java Map.put () .

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

Но отсутствующая функция скорее соответствует Java Set.add() method.

Добавляет указанный элемент в этот набор, если он еще не существует (необязательная операция).Более формально, добавляет указанный элемент e в этот набор, если набор не содержит элемент e2, такой что (e == null? E2 == null: e.equals (e2)).Если этот набор уже содержит элемент, вызов оставляет набор без изменений и возвращает false.

Как бы вы создали JSON API, который позволял бы оба типа операций для массового исправления очень большой коллекциис элементами, которые содержат десятки необязательных полей?


Обновление

Спасибо @ chad-jensen за идею правил приоритизации атрибутов.Упомянутый документ предлагает довольно гибкий подход, поэтому я попытался адаптировать его к своим потребностям.Я думаю, что у меня будет две операции: «инициализация» с более низким приоритетом и «добавление» или, скорее, «замена» с более высоким приоритетом.

Затем, в моем примере, данные JSON, отправленные клиентом А иклиент B будет выглядеть следующим образом.

Данные, отправленные клиентом A, который обновляет поле "optional2" с более низким приоритетом и обновляет поле "optional1" с самым высоким приоритетом.

{
    "email": "user@organization.com",
    "initialize":
    {
        "optional2": "A"
    },
    "replace":
    {
        "optional1": "A"
    }
}

Данные, отправленные клиентом B, который обновляет поля "optional1" и "optional3" с более низким приоритетом и обновляет поле "optional2" с самым высоким приоритетом.

{
    "email": "user@organization.com",
    "initialize":
    {
        "optional1": "B",
        "optional3": "B"
    },
    "replace":
    {
        "optional2": "B"
    }
}

1 Ответ

0 голосов
/ 28 сентября 2018

Вам понадобится какое-то отображение приоритетов, которое решает, какие поля имеют приоритет для каждого клиента.

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

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

Я нашел документ, который мог бы прояснить, что я имею в виду (он немного конкретен в отношении некоторых сторонних инструментов, но концепция есть): https://www.ibm.com/support/knowledgecenter/en/SSPLFC_7.2.0/UserGuide/c_cmdb_reconcilation_overview.html

...