如何在Web服务更新消息(DTO)中使用可选属性? [英] How to use optional attributes in web service update messages (DTOs)?
问题描述
背景
假设您有一个(SOAP)Web服务BookService
,用于管理图书馆中的图书.在信息模型中,假定Book
实体具有以下属性:
-
id
-
author
-
publisher
-
title
-
shelfId
为了操纵数据,定义了四个Web服务操作:
-
AddBook
-
GetBook
-
UpdateBook
-
DeleteBook
为每个操作定义了请求和响应消息.但是,更新消息XML模式的设计更为复杂.我们希望达到以下品质:
- R1:可以重置/删除属性的先前值.说您再也不会将书保留在图书馆中,因此想重置/清空/删除该特定书的属性
shelfId
的属性值. - R2:避免Web服务中的聊天.请参见)或显式设置为null的元素(即
<shelfId xsi:nil="true"/>
)将被解释为先前值的删除. - 突出显示更改或仅发送差异.
- 发送整个业务文档,但使用专用于此目的的属性标记修改后的元素.示例:
<author dirty="true">Hemingway<author/>
.然后,服务提供者仅更新那些标记为脏的元素,而忽略其他元素. - 在消息模式中,将所有元素(但标识符
id
)设置为具有minOccurs="0"
.使用者仅发送 要修改的元素.遗漏的元素在语义上必须 not 解释为删除.为了删除值,必须使用显式XMLNULL
值.例如:<shelfId xsi:nil="true"/>
. - 发送整个业务文档,但还要提交以前阅读的文档的副本.然后,提供者可以比较两个文档,并仅 更新新文档和先前文档的属性.
- 发送整个业务文档,但使用专用于此目的的属性标记修改后的元素.示例:
- 定义多个操作.
UpdateBook
不仅要使用一个操作,还要根据您认为必须更新的元素定义多个操作,例如UpdateBookAuthor
,UpdateBookPublisher
等.这些元素中的每一个都将仅具有必选元素,并且要删除这些元素,请使用XML的显式NULL,例如<shelfId xsi:nil="true"/>
. - 对于将每个字段的带有时间戳/版本的乐观锁定存储在数据库中的情况(例如
authorVersion
)=> Alt 2 提供了一种让多个用户修改不同部分的方式,例如相同Book
的author
和publisher
并发故障的风险较小. - 对于将整个
Book
的单个时间戳/版本的乐观锁定存储在数据库中的情况=> Alt 2 相对于 Alt 1 没有真正的优势.即使更新仅修改了一个字段,但请求的版本号过旧也会导致错误. - 对于未使用并发控制或乐观/悲观锁定的情况=>与旧数据覆盖相比, Alt 2 产生的风险要低于 Alt 1 ,但是仍然存在其他不一致的情况变化可能会带来问题.
id
author
publisher
title
shelfId
AddBook
GetBook
UpdateBook
DeleteBook
- R1: Possibility to reset/delete previous values of an attribute. E.g. say that you no more will keep the book in the library and thereby would like to reset/empty/remove the attribute value of the attribute
shelfId
for that specific book. - R2: Avoid chattiness in the web services. See the anti-pattern Chatty Services.
- R3: Prepare for future requirements on Concurrency Control and Optimistic Locking. We may want to minimize (or remove) the risk of having updates made on based of old information.
- Send the entire business document. Left-out elements (having
minOccurs="0"
in the schema) OR elements explicitly set to null, i.e.<shelfId xsi:nil="true"/>
, would be interpreted as deletion of the previous values. - Highlight the changes or send only the diff.
- Send the entire business document, but mark the modified elements using an attribute specific to this purpose. Example:
<author dirty="true">Hemingway<author/>
. The provider of the service then updates only those elements marked as dirty and ignores the other ones. - In the message schema, set all elements, but the identifier
id
, to haveminOccurs="0"
. The consumer sends only those elements which are to be modified. A left-out element must not semantically be interpreted as a deletion. In order to delete a value the explicit XMLNULL
value must be used. Example:<shelfId xsi:nil="true"/>
. - Send the entire business document, but also submit a copy of the previously read document. The provider can then compare the two documents and update only those attributes for which the new and the previous documents differ.
- Send the entire business document, but mark the modified elements using an attribute specific to this purpose. Example:
- Define multiple operations. Instead of only using one operation,
UpdateBook
, define multiple operation based on which elements you believe will have to be updated, e.g.UpdateBookAuthor
,UpdateBookPublisher
and so on. Each of these will have only mandatory elements and for removal of elements use the explicit NULL of XML, e.g.<shelfId xsi:nil="true"/>
. - For situations when optimistic locking with timestamps/versions for each field is stored in the database (e.g.
authorVersion
) => Alt 2 provides a way of letting multiple users modify different parts, such asauthor
andpublisher
, of the sameBook
concurrently with less risk of having faults. - For situations when optimistic locking with one single timestamp/version for the entire
Book
is stored in the database => No real advantage of Alt 2 over Alt 1. Even if an update only modifies one field, a too old version number of the request would result in a fault. - For situations when no concurrency control or optimistic/pessimistic locking is used => Alt 2 gives less risk than Alt 1 of overwriting with old data, but still other inconsistent changes may give problems.
讨论
Alt 3 的优点是易于理解,但缺点是,如果需要更新Book
实体中的多个字段,使用者需要调用多个操作.这会使服务变得混乱"(请参阅上面的R3),从而导致性能下降.
Alt 2 比 Alt 1 更复杂,但是与优化并发控制相关的 Alt 2 有一些优点:
还有另一种情况,其中 Alt 2 (和 Alt 3 )优于 Alt 1 .使用者可能不会存储有关Book
实体的所有数据.例如,在更新书架信息时,如果机器人不需要跟踪(缓存)作者的信息,而只是跟踪书架,则可以更有效地编程从书架上捡书的机器人.
Alt 2.3 中方法的优点是,消费者提交以前版本的完整副本而不是版本号或时间戳,这是因为数据库中不需要专用列来存储版本号或时间戳
总而言之,我想说 Alt 2.2 在大多数情况下似乎是最吸引人的.这里的挑战只是反序列化XML的框架必须能够将遗漏的元素与显式设置为NULL的元素区分开,例如<shelfId xsi:nil="true"/>
. 在此处查看有关此主题的帖子.
问题
您会选择哪种选择?您是否看到其他更好的选择?您如何看待这次讨论?
正如您已经讨论过的,alt 2.2似乎是相当可行的.但是,框架通常会忽略minoccurs = 0和nil之间的区别,并且对于许多用户(可能是此接口)也很难理解.因此,我将进行一种变体,其中在一个更改消息中,当您要使它们无效时,您用每个属性显式标记.
etag可能是用于乐观锁定的一种标准.我认为您已经广泛讨论了锁定机制的含义.它应该按照您描述的方式工作.Alt 1在消息设计和使用/实现方面要简单得多,并且如果流量不是问题,并且对整个对象进行乐观锁定就足够了(大多数情况下是恕我直言),这也可以很好地发挥作用./p>
您还应考虑到在某些业务流程中,不同属性的更改是相互依赖的,因此对属性进行单独的版本控制是没有意义的,因为即使仅更改了另一个属性,对一个属性的更改也可能是错误的更改时已过时.
如果是这种情况,这是选择1的另一个原因.
BACKGROUND
Assume you have a (SOAP) web service, BookService
, managing books in a library. In the information model assume that the Book
entity has the following attributes:
In order to manipulate the data four web service operations are defined:
Request and response message are defined for each operation. However, the design of the update message XML schemas is more complicated. We would like to achieve the following qualities:
DESIGN ALTERNATIVES
I see three mayor alternatives, of which one has several sub-options, to design the update message(s):
DISCUSSION
Alt 3 has the advantage of being simple to understand, but the drawback is that consumers would need to invoke multiple operations in case multiple fields in the Book
entity should be updated. This makes the service "chatty" (see R3 above), giving performance penalties.
Alt 2 is more complex than Alt 1, but there are some advantages of Alt 2 related to Optimistic Concurrency Control:
There is yet another situation in which Alt 2 (and Alt 3) gives an advantage over Alt 1. The consumer may not store all the data about the Book
entity. For example, a robot picking the books from their shelf's may be programmed more effectively if it doesn't need to keep track (cache) on the information on the author, but just the shelf, when updating the shelf information.
An advantage of the approach in Alt 2.3, where the consumer submits entire copies of previous versions instead of version numbers or timestamps, is that no dedicated column in the database is needed for version number or timestamp.
To sum it up I would say Alt 2.2 looks like the most attractive one for most cases. The challenge here is just that the frameworks deserializing the XML must be able to distinguish a left-out element from an element explicitly set to NULL, e.g. <shelfId xsi:nil="true"/>
. See a post on this topic here.
QUESTION
Which of the alternatives would you go for? Do you see other, better alternatives? What do you think of the discussion?
As you have already discussed, alt 2.2 seems to be rather feasible. However, the distinction between minoccurs=0 and nil is often ignored by frameworks and is also hard to understand for many users (potentially of this interface). Thus I would go for a variation, where in one change message you mark with every attribute explicitly when you want them to be nullified.
etag could be one standard to be used for optimistic locking. I think you have discussed the implications of locking mechanisms already extensively. It should work the way you describe.
Alt 1 is a lot simpler, both in message design and usage/implementation and if traffic is not an issue and optimistic locking for whole objects is enough (which is most often the case imho), that could also work well.
You should also take into account that with some business processes, changes of different attributes are interdependent so it doesn't make sense to have separate versioning for attributes, since a change at one attribute can be wrong even if only another attribute was outdated at the time of change.
If this can be the case, it is another reason for alt 1.
这篇关于如何在Web服务更新消息(DTO)中使用可选属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!