ФОН
Предположим, у вас есть (SOAP) веб-служба, BookService
, управляющая книгами в библиотеке. В информационной модели предположим, что объект Book
имеет следующие атрибуты:
id
author
publisher
title
shelfId
Для манипулирования данными определены четыре операции веб-службы:
AddBook
GetBook
UpdateBook
DeleteBook
Запрос и ответное сообщение определяются для каждой операции. Однако дизайн XML-схем сообщений об обновлении более сложен. Мы хотели бы достичь следующих качеств:
- R1: возможность сброса / удаления предыдущих значений атрибута. Например. скажем, что вы больше не будете хранить книгу в библиотеке и, следовательно, хотели бы сбросить / очистить / удалить значение атрибута атрибута
shelfId
для этой конкретной книги.
- R2: Избегайте разговоров в веб-службах. См. анти-шаблонный Chatty Services .
- R3: Подготовка к будущим требованиям по контролю параллелизма и оптимистической блокировке. Мы можем минимизировать (или устранить) риск того, что обновления будут производиться на основе старой информации.
ПРОЕКТНЫЕ АЛЬТЕРНАТИВЫ
Я вижу три варианта мэра, один из которых имеет несколько подопций для разработки сообщений об обновлении:
- Отправка всего бизнес-документа. Исключенные элементы (имеющие
minOccurs="0"
в схеме) ИЛИ элементы, явно заданные равными нулю, то есть <shelfId xsi:nil="true"/>
, будут интерпретироваться как удаление предыдущих значений.
- Выделите изменения или отправьте только разницу.
- Отправьте весь бизнес-документ, но пометьте измененные элементы, используя атрибут, соответствующий этой цели. Пример:
<author dirty="true">Hemingway<author/>
. Затем поставщик услуг обновляет только те элементы, которые помечены как грязные, и игнорирует остальные.
- В схеме сообщения установите для всех элементов, кроме идентификатора
id
, значение minOccurs="0"
. Потребитель отправляет только те элементы, которые должны быть изменены. Исключенный элемент должен , а не семантически интерпретироваться как удаление. Для удаления значения необходимо использовать явное значение XML NULL
. Пример: <shelfId xsi:nil="true"/>
.
- Отправьте весь бизнес-документ, а также отправьте копию ранее прочитанного документа. Затем поставщик может сравнить два документа и обновить только тех атрибутов, для которых новый и предыдущий документы различаются.
- Определите несколько операций. Вместо использования только одной операции,
UpdateBook
, определите несколько операций на основе того, какие элементы, по вашему мнению, должны быть обновлены, например, UpdateBookAuthor
, UpdateBookPublisher
и так далее. Каждый из них будет иметь только обязательные элементы, а для удаления элементов используйте явный NULL XML, например, <shelfId xsi:nil="true"/>
.
ОБСУЖДЕНИЕ
Alt 3 обладает тем преимуществом, что его легко понять, но недостатком является то, что потребителям придется вызывать несколько операций в случае обновления нескольких полей в сущности Book
. Это делает службу «болтливой» (см. R3 выше), что снижает производительность.
Alt 2 более сложный, чем Alt 1 , но есть некоторые преимущества Alt 2 , связанные с оптимистичным управлением параллелизмом:
- Для ситуаций, когда оптимистическая блокировка с временными метками / версиями для каждого поля хранится в базе данных (например,
authorVersion
) => Alt 2 обеспечивает способ, позволяющий нескольким пользователям изменять различные части, такие как author
и publisher
того же Book
одновременно с меньшим риском возникновения неисправностей. - Для ситуаций, когда оптимистическая блокировка с одной временной меткой / версией для всего
Book
хранится в базе данных => Нет реального преимущества Alt 2 над Alt 1 .Даже если обновление изменяет только одно поле, слишком старый номер версии запроса может привести к ошибке. - Для ситуаций, когда не используется управление параллелизмом или оптимистическая / пессимистическая блокировка => Alt 2 дает меньший риск, чем Alt 1 перезаписи старыми данными, но все же другие противоречивые изменения могут вызвать проблемы.
Существует еще одна ситуация, в которой Alt 2 (и Alt 3 ) дает преимущество перед Alt 1 .Потребитель не может хранить все данные о сущности Book
.Например, робот, собирающий книги с их полок, может быть запрограммирован более эффективно, если ему не нужно отслеживать (кэшировать) информацию об авторе, а только полку, при обновлении информации о полке.
Преимущество подхода в Alt 2.3 , где потребитель представляет полные копии предыдущих версий вместо номеров версий или временных отметок, заключается в том, что для номера версии или временной отметки не требуется выделенный столбец в базе данных.
Подводя итог, я бы сказал, что Alt 2.2 выглядит наиболее привлекательным в большинстве случаев.Сложность здесь заключается в том, что фреймворки, десериализирующие XML, должны иметь возможность отличать исключенный элемент от элемента, явно установленного в NULL, например, <shelfId xsi:nil="true"/>
. Смотрите пост на эту тему здесь.
ВОПРОС
Какой из вариантов вы бы выбрали?Видите ли вы другие, лучшие альтернативы?Что вы думаете о дискуссии?