Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Describe semantics of etags within a delta payload. #1958

Merged
merged 17 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions docs/odata-protocol/odata-protocol.html
Original file line number Diff line number Diff line change
Expand Up @@ -535,11 +535,16 @@ <h2 id="11-changes-from-earlier-versions"><a name="ChangesfromEarlierVersions" h
<td><a href="https://github.com/oasis-tcs/odata-specs/issues/534">534</a></td>
</tr>
<tr class="odd">
<td><a href="#ReplaceaCollectionofEntities">Section 11.4.13</a></td>
<td>Describe semantics for using <code>continue-on-error</code> when replacing a collection of entities.</td>
<td><a href="https://github.com/oasis-tcs/odata-specs/issues/358">358</a></td>
</tr>
<tr class="even">
<td><a href="#Conformance">Section 12</a></td>
<td>Allow <code>400 Bad Request</code> in addition to <code>501 Not Implemented</code> for unsupported functionality</td>
<td><a href="https://github.com/oasis-tcs/odata-specs/issues/391">391</a></td>
</tr>
<tr class="even">
<tr class="odd">
<td><a href="#InteroperableODataClients">Section 12.3</a></td>
<td>Encoding of plus character in URLs</td>
<td><a href="https://github.com/oasis-tcs/odata-specs/issues/485">485</a></td>
Expand Down Expand Up @@ -2602,33 +2607,41 @@ <h3 id="11412-update-a-collection-of-entities"><a name="UpdateaCollectionofEntit
<p>Added/changed entities are applied as <a href="#UpsertanEntity">upserts</a>, and deleted entities as <a href="#DeleteanEntity">deletions</a>. Non-key properties of deleted entities are ignored. The top-level collection may include added and deleted links, and related entities represented inline are updated according to the rules for <a href="#UpdateRelatedEntitiesWhenUpdatinganEntity">treating related entities when updating an entity</a>.</p>
<p>Clients MAY associate an id with individual nested entities in the request by using the <a href="https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#ContentID"><code>Core.ContentID</code></a> term defined in <a href="#ODataVocCore">OData-VocCore</a>. Services that respond with <a href="#ResponseCode200OK"><code>200 OK</code></a> SHOULD annotate the entities in the response using the same <a href="https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#ContentID"><code>Core.ContentID</code></a> value as specified in the request.</p>
<p>Services SHOULD advertise support for updating a collection using a delta payload through the <code>DeltaUpdateSupported</code> property of the <a href="https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Capabilities.V1.md#UpdateRestrictionsType"><code>Capabilities.UpdateRestrictions</code></a> term, and SHOULD advertise support for returning the <a href="https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#ContentID"><code>Core.ContentID</code></a> through the <code>ContentIDSupported</code> property of the <a href="https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Capabilities.V1.md#DeepUpdateSupportType"><code>Capabilities.DeepUpdateSupport</code></a> term, both defined in <a href="#ODataVocCap">OData-VocCap</a>.</p>
<p>For each entity being updated or removed, clients MAY specify an <a href="#UseofETagsforAvoidingUpdateConflicts">ETag</a> value obtained from a previous request. If an ETag is provided that does not match the ETag value of the entity being updated or removed, or if an ETag is provided when adding or updating an entity that does not currently exist, then services that support ETags MUST NOT apply the change and instead report a <code>412 Precondition Failed</code> error according to the appropriate <a href="#ErrorHandlingwhenUpdatingaCollectionofEntities"><code>continue-on-error</code></a> behavior. The special value <code>*</code> can be used to match any existing entity but fail if the entity does not already exist.</p>
<p>For each entity being updated or removed, clients MAY specify an <a href="#UseofETagsforAvoidingUpdateConflicts">ETag</a> value obtained from a previous request. If an ETag is provided that does not match the ETag value of the entity being updated or removed, or if an ETag is provided when adding or updating an entity that does not currently exist, then services that support ETags MUST NOT apply the change and instead <a href="#ErrorHandlingwhenUpdatingaCollectionofEntities">report</a> a <code>412 Precondition Failed</code> error. The special value <code>*</code> can be used to match any existing entity but fail if the entity does not already exist.</p>
<p>The response, if requested, is a delta payload, in the same structure and order as the request payload, representing the applied changes.</p>
<details open><summary>
<h4 id="114121-error-handling-when-updating-a-collection-of-entities"><a name="ErrorHandlingwhenUpdatingaCollectionofEntities" href="#ErrorHandlingwhenUpdatingaCollectionofEntities">11.4.12.1 Error Handling when Updating a Collection of Entities</a></h4>
</summary>
<p>If the <code>continue-on-error</code> preference has not been applied, and the service is unable to apply all of the changes in the request, then it MUST return an error response and MUST NOT apply any of the changes specified in the request payload.</p>
<p>If the <a href="#Preferencecontinueonerrorodatacontinueonerror"><code>continue-on-error</code></a> preference has been applied and any errors occur in processing the changes, then a delta response MUST be returned regardless of the <a href="#Preferencereturnrepresentationandreturnminimal"><code>return</code></a> preference and MUST contain at least the failed changes. The service represents failed changes in the delta response as follows:</p>
<ul>
<li>Failed deletes in the request MUST be represented in the response as either entities or entity references, annotated with the term <code>Core.DataModificationException</code>, see <a href="#ODataVocCore">OData-VocCore</a>. If the deleted entity specified a reason of <code>deleted</code>, the value of <code>failedOperation</code> MUST be <code>delete</code>, otherwise <code>unlink</code>.</li>
<li>Failed deletes in the request MUST be represented in the response as either entities or entity references, annotated with the term <code>Core.DataModificationException</code>, see <a href="#ODataVocCore">OData-VocCore</a>. If the deleted entity specified a reason of <code>deleted</code>, or the target collection is an entity set or contained navigation property, then the value of <code>failedOperation</code> MUST be <code>delete</code>, otherwise <code>unlink</code>.</li>
<li>Failed inserts within the request MUST be represented in the response as deleted entities annotated with the term <code>Core.DataModificationException</code> with a <code>failedOperation</code> value of <code>insert</code>.</li>
<li>Failed updates within the request MUST be annotated in the response with the term <code>Core.DataModificationException</code> with a <code>failedOperation</code> value of <code>update</code>. If the update fails due to an unmatched ETag, the <code>responseCode</code> MUST be present with a value of <code>412</code>.</li>
<li>Failed updates within the request SHOULD be annotated in the response with the term <code>Core.DataModificationException</code> with a <code>failedOperation</code> value of <code>update</code>.</li>
<li>Failed added links within the request MUST represented in the response as deleted links annotated with the term <code>Core.DataModificationException</code> with a <code>failedOperation</code> value of <code>link</code>.</li>
<li>Failed deleted links within the request MUST represented in the response as added links annotated with the term <code>Core.DataModificationException</code> with a <code>failedOperation</code> value of <code>unlink</code>.</li>
<li>Collections within the request MUST be represented in the response as a collection with the current values and membership of the collection as it exists in the service after processing the request.</li>
<li>Delta collections within the request are returned as delta collections in the response, according to these same rules.</li>
<li>Collections within the request are represented as collections in the response according to the rules specified in <a href="#ErrorHandlingwhenReplacingaCollectionofEntities">Replace a Collection of Entities</a>.</li>
</ul>
<p>If an individual change fails due to a failed dependency, it MUST be annotated with the term <a href="https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#DataModificationException"><code>Core.DataModificationException</code></a> and SHOULD specify a <code>responseCode</code> of <code>424</code> (<a href="#ResponseCode424FailedDependency">Failed Dependency</a>).</p>
<p>If the <code>continue-on-error</code> preference has not been applied, and the service is unable to apply all of the changes in the request, then it MUST return an error response and MUST NOT apply any of the changes specified in the request payload.</p>
</details>
</details>
<details open><summary>
<h3 id="11413-replace-a-collection-of-entities"><a name="ReplaceaCollectionofEntities" href="#ReplaceaCollectionofEntities">11.4.13 Replace a Collection of Entities</a></h3>
</summary>
<p>Collections of entities can be replaced by submitting a <code>PUT</code> request to the resource path of the collection. The body of the request MUST be the representation of the complete collection of replacement entities. In this case all entities provided in the request are applied as <a href="#UpsertanEntity">upserts</a>, and any entities not provided in the request are deleted. For each entity being updated, clients MAY specify an <a href="#UseofETagsforAvoidingUpdateConflicts">ETag</a> value obtained from a previous request. If an ETag is provided that does not match the ETag value of the entity being updated, or if an ETag is provided for an entity that does not currently exist, then services that support ETags MUST NOT apply the change and instead report a <code>412 Precondition Failed</code> error according to the appropriate <a href="#ErrorHandlingwhenReplacingaCollectionofEntities"><code>continue-on-error</code></a> behavior. The special ETag value <code>*</code> can be used to match any existing entity but fail if the entity does not already exist.</p>
<p>Collections of entities can be replaced by submitting a <code>PUT</code> request to the resource path of the collection. The body of the request MUST be the representation of the complete collection of replacement entities. In this case all entities provided in the request are applied as <a href="#UpsertanEntity">upserts</a>, and any entities not provided in the request are deleted.</p>
<p>For each entity being updated, clients MAY specify an <a href="#UseofETagsforAvoidingUpdateConflicts">ETag</a> value obtained from a previous request. If an ETag is provided that does not match the ETag value of the entity being updated, or if an ETag is provided for an entity that does not currently exist, then services that support ETags MUST NOT apply the change and instead <a href="#ErrorHandlingwhenReplacingaCollectionofEntities">report</a> a <code>412 Precondition Failed</code>. The special ETag value <code>*</code> can be used to match any existing entity but fail if the entity does not already exist.</p>
<details open><summary>
<h4 id="114131-error-handling-when-replacing-a-collection-of-entities"><a name="ErrorHandlingwhenReplacingaCollectionofEntities" href="#ErrorHandlingwhenReplacingaCollectionofEntities">11.4.13.1 Error Handling when Replacing a Collection of Entities</a></h4>
</summary>
<p>If the <code>continue-on-error</code> preference has been applied and any errors occur in processing the changes, then a response MUST be returned regardless of the <a href="#Preferencereturnrepresentationandreturnminimal"><code>return</code></a> preference, and MUST contain the full membership and values of the collection as it exists in the service.</p>
<p>If the <code>continue-on-error</code> preference has not been applied, and the service is unable to apply all of the changes in the request, then it MUST return an error response and MUST NOT apply any of the changes specified in the request payload.</p>
<p>If the <code>continue-on-error</code> preference has been applied and any errors occur in processing the changes, then a response MUST be returned regardless of the <a href="#Preferencereturnrepresentationandreturnminimal"><code>return</code></a> preference, and MUST contain the full membership and values of the collection as it exists in the service, as follows:</p>
<ul>
<li>Entities missing in the request that cannot be removed from the collection MUST be represented in the response as either entities or entity references, and MAY be annotated with the term <code>Core.DataModificationException</code>, see <a href="#ODataVocCore">OData-VocCore</a>. If the target collection is an entity set or containment navigation property, then the value of <code>failedOperation</code> MUST be <code>delete</code>, otherwise <code>unlink</code>.</li>
<li>Failed inserts within the request MUST NOT be represented in the response.</li>
<li>Failed updates within the request MUST be represented in the response with their current values and MAY be annotated with the term <code>Core.DataModificationException</code> with a <code>failedOperation</code> value of <code>update</code>.</li>
<li>Collections within the request MUST also be represented in the response following these same rules.</li>
</ul>
</details>
</details>
<details open><summary>
Expand Down
Loading