Skip to content

Commit

Permalink
Describe semantics of etags within a delta payload. (#1958)
Browse files Browse the repository at this point in the history
Fixes #358

---------

Co-authored-by: Ralf Handl <[email protected]>
  • Loading branch information
mikepizzo and ralfhandl authored Jul 31, 2024
1 parent 7a7e40c commit b4c4fcc
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 80 deletions.
1 change: 1 addition & 0 deletions docs/odata-json-format/odata-json-format.html
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,7 @@ <h2 id="152-addedchanged-entity"><a name="AddedChangedEntity" href="#AddedChange
<p>Any entity in an update request that has neither the <code>id</code> control information, nor the primary or alternate key values of an existing entity, are treated as an added entity.</p>
<p>Added entities MUST include all available selected properties and MAY include additional, unselected properties. Collection-valued properties are treated as atomic values; any collection-valued properties returned from a delta request MUST contain all current values for that collection.</p>
<p>Changed entities MUST include all available selected properties that have changed, and MAY include additional properties.</p>
<p>Added or changed entities MAY include <a href="#ControlInformationetagodataetag">ETags</a>.</p>
<p>Entities include control information for selected navigation links based on <a href="#ControllingtheAmountofControlInformationinResponses"><code>metadata</code></a>.</p>
</details>
<details open><summary>
Expand Down
2 changes: 2 additions & 0 deletions docs/odata-json-format/odata-json-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -2212,6 +2212,8 @@ collection.
Changed entities MUST include all available selected properties that
have changed, and MAY include additional properties.

Added or changed entities MAY include [ETags](#ControlInformationetagodataetag).

Entities include control information for selected navigation links based
on [`metadata`](#ControllingtheAmountofControlInformationinResponses).

Expand Down
64 changes: 50 additions & 14 deletions docs/odata-protocol/odata-protocol.html

Large diffs are not rendered by default.

92 changes: 56 additions & 36 deletions docs/odata-protocol/odata-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,11 @@ For complete copyright information please see the full Notices section in an App
- [11.4.10 Managing Members of an Ordered Collection](#ManagingMembersofanOrderedCollection)
- [11.4.11 Positional Inserts](#PositionalInserts)
- [11.4.12 Update a Collection of Entities](#UpdateaCollectionofEntities)
- [11.4.13 Update Members of a Collection](#UpdateMembersofaCollection)
- [11.4.14 Delete Members of a Collection](#DeleteMembersofaCollection)
- [11.4.12.1 Error Handling when Updating a Collection of Entities](#ErrorHandlingwhenUpdatingaCollectionofEntities)
- [11.4.13 Replace a Collection of Entities](#ReplaceaCollectionofEntities)
- [11.4.13.1 Error Handling when Replacing a Collection of Entities](#ErrorHandlingwhenReplacingaCollectionofEntities)
- [11.4.14 Update Members of a Collection](#UpdateMembersofaCollection)
- [11.4.15 Delete Members of a Collection](#DeleteMembersofaCollection)
- [11.5 Operations](#Operations)
- [11.5.1 Binding an Operation to a Resource](#BindinganOperationtoaResource)
- [11.5.2 Applying an Operation to Members of a Collection](#ApplyinganOperationtoMembersofaCollection)
Expand Down Expand Up @@ -356,6 +359,7 @@ Section | Feature / Change | Issue
[Section 11.4](#DataModification)| Response code `204 No Content` after successful data modification if requested response could not be constructed| [443](https://github.com/oasis-tcs/odata-specs/issues/443)
[Section 11.4.4](#UpsertanEntity)| Upserts to single-valued non-containment navigation properties| [455](https://github.com/oasis-tcs/odata-specs/issues/455)
[Section 11.4.9.3](#UpdateaComplexProperty)| Setting a complex property to a different type| [534](https://github.com/oasis-tcs/odata-specs/issues/534)
[Section 11.4.13](#ReplaceaCollectionofEntities)| Semantics of `continue-on-error` when replacing a collection of entities | [358](https://github.com/oasis-tcs/odata-specs/issues/358)
[Section 12](#Conformance) | Allow `400 Bad Request` in addition to `501 Not Implemented` for unsupported functionality| [391](https://github.com/oasis-tcs/odata-specs/issues/391)
[Section 12.3](#InteroperableODataClients) | Encoding of plus character in URLs | [485](https://github.com/oasis-tcs/odata-specs/issues/485)

Expand Down Expand Up @@ -3989,6 +3993,8 @@ A delta payload represents changes to a known state. A delta payload
includes added entities, changed entities, and deleted entities, as well
as a representation of added and removed relationships.

Services that support the use of [ETags](#UseofETagsforAvoidingUpdateConflicts) for optimistic concurrency control SHOULD return ETag values for added or changed entities within the delta payload.

Delta payloads can be [requested](#RequestingChanges) from the service
using a delta link or provided as updates to the service.

Expand Down Expand Up @@ -5019,60 +5025,74 @@ through the `ContentIDSupported` property of the
[`Capabilities.DeepUpdateSupport`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Capabilities.V1.md#DeepUpdateSupportType)
term, both defined in [OData-VocCap](#ODataVocCap).

For each entity being updated or removed, clients MAY specify an [ETag](#UseofETagsforAvoidingUpdateConflicts) 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](#ErrorHandlingwhenUpdatingaCollectionofEntities) a `412 Precondition Failed` error. The special value `*` can be used to match any existing entity but fail if the entity does not already exist.

The response, if requested, is a delta payload, in the same structure
and order as the request payload, representing the applied changes.

If the client requests `continue-on-error` behavior and the service encounters any errors while processing the request, then it MUST either fail the entire request without applying any changes or include a [`Preference-Applied`](#HeaderPreferenceApplied) header in the response indicating that the [`continue-on-error`](#Preferencecontinueonerrorodatacontinueonerror) preference has been applied. In this case, the delta response payload MUST be returned
#### <a name="ErrorHandlingwhenUpdatingaCollectionofEntities" href="#ErrorHandlingwhenUpdatingaCollectionofEntities">11.4.12.1 Error Handling when Updating a Collection of Entities</a>

If the `continue-on-error` 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.

If the [`continue-on-error`](#Preferencecontinueonerrorodatacontinueonerror) preference has been applied and any errors occur in processing the changes, then a delta response MUST be returned
regardless of the [`return`](#Preferencereturnrepresentationandreturnminimal)
preference and MUST contain at least the failed changes. The service
represents failed changes in the delta response as follows:
- Failed deletes in the request MUST be
represented in the response as either entities or entity references,
annotated with the term `Core.DataModificationException`, see
- Failed deletes in the request MUST be represented in the response as either entities or entity references, annotated with the term `Core.DataModificationException`, see
[OData-VocCore](#ODataVocCore). If the deleted entity specified a reason
of `deleted`, the value of `failedOperation` MUST be `delete`, otherwise
`unlink`.
of `deleted`, or the target collection is an entity set or containment navigation property,
then the value of `failedOperation` MUST be `delete`, otherwise `unlink`.
- Failed inserts within the request MUST
be represented in the response as deleted entities annotated with the term
`Core.DataModificationException` with a `failedOperation` value of
`insert`.
- Failed updates within the request SHOULD
be annotated in the response with the term `Core.DataModificationException`
with a `failedOperation` value of `update`.
- Failed added links within the request
MUST represented in the response as deleted links annotated with the term
`Core.DataModificationException` with a `failedOperation` value of
`link`.
- Failed deleted links within the request
MUST represented in the response as added links annotated with the term
`Core.DataModificationException` with a `failedOperation` value of
`unlink`.
- 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.
- Failed updates within the request SHOULD be annotated in the response with the term `Core.DataModificationException` with a `failedOperation` value of `update`.
- Failed added links within the request MUST be represented in the response as deleted links annotated with the term `Core.DataModificationException` with a `failedOperation` value of `link`.
- Failed deleted links within the request MUST be represented in the response as added links annotated with the term `Core.DataModificationException` with a `failedOperation` value of `unlink`.
- Delta collections within the request are returned as delta collections in the response, according to these same rules.
- Collections within the request are represented as collections in the response according to the rules specified in [Replace a Collection of Entities](#ErrorHandlingwhenReplacingaCollectionofEntities).

If an individual change fails due to a failed dependency, it MUST be
annotated with the term [`Core.DataModificationException`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#DataModificationException) and SHOULD specify
a `responseCode` of `424` ([Failed Dependency](#ResponseCode424FailedDependency)).

Alternatively, the verb `PUT` can be used, in which case the request
body MUST be the representation of a collection of entities. In this
### <a name="ReplaceaCollectionofEntities" href="#ReplaceaCollectionofEntities">11.4.13 Replace a Collection of Entities</a>

Collections of entities can be replaced by submitting a `PUT` 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
[upserts](#UpsertanEntity), and any entities not provided in the request
are deleted. In this case, if the `continue-on-error` preference has
been specified, and the request returns a success response code, then a
response MUST be returned regardless of the
[`return`](#Preferencereturnrepresentationandreturnminimal) preference, and MUST
contain the full membership and values of the collection as it exists in
the service.
are deleted.

If the `continue-on-error` preference has not been specified, and the
For each entity being updated, clients MAY specify an [ETag](#UseofETagsforAvoidingUpdateConflicts)
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](#ErrorHandlingwhenReplacingaCollectionofEntities)
a `412 Precondition Failed`. The special ETag value `*` can be used to match any existing entity but fail if the entity does not already exist.

#### <a name="ErrorHandlingwhenReplacingaCollectionofEntities" href="#ErrorHandlingwhenReplacingaCollectionofEntities">11.4.13.1 Error Handling when Replacing a Collection of Entities</a>

If the `continue-on-error` 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.

### <a name="UpdateMembersofaCollection" href="#UpdateMembersofaCollection">11.4.13 Update Members of a Collection</a>
If the `continue-on-error` preference has been applied and any errors occur in processing the changes, then a response MUST be returned regardless of the
[`return`](#Preferencereturnrepresentationandreturnminimal) preference, and MUST
contain the full membership and values of the collection as it exists in
the service, as follows:
- 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 SHOULD be annotated with the term `Core.DataModificationException`, see
[OData-VocCore](#ODataVocCore). If the target collection is an entity set or containment navigation property, then the value of `failedOperation` MUST be `delete`, otherwise `unlink`.
- Failed inserts within the request MUST NOT be represented in the response.
- Failed updates within the request MUST be represented in the response with
their current values and SHOULD be annotated with the term `Core.DataModificationException`
with a `failedOperation` value of `update`.
- Collections within the request MUST also be represented in the response following these same rules.

### <a name="UpdateMembersofaCollection" href="#UpdateMembersofaCollection">11.4.14 Update Members of a Collection</a>

Members of a collection can be updated by submitting a `PATCH` request
to the URL constructed by appending `/$each` to the resource path of the
Expand Down Expand Up @@ -5129,7 +5149,7 @@ service is unable to update all of the members identified by the
request, then it MUST return an error response and MUST NOT apply any
updates.

### <a name="DeleteMembersofaCollection" href="#DeleteMembersofaCollection">11.4.14 Delete Members of a Collection</a>
### <a name="DeleteMembersofaCollection" href="#DeleteMembersofaCollection">11.4.15 Delete Members of a Collection</a>

Members of a collection can be deleted by submitting a `DELETE` request
to the URL constructed by appending `/$each` to the resource path of the
Expand Down Expand Up @@ -6553,8 +6573,8 @@ or upsert operation that returns `204 No Content` ([section 8.3.4](#HeaderODataE
31. SHOULD support `DELETE` to set an individual property to null
([section 11.4.9.2](#SetaValuetoNull))
32. SHOULD support deep inserts ([section 11.4.2.2](#CreateRelatedEntitiesWhenCreatinganEntity))
33. MAY support set-based updates ([section 11.4.13](#UpdateMembersofaCollection)) or deletes
([section 11.4.14](#DeleteMembersofaCollection)) to members of a collection
33. MAY support set-based updates ([section 11.4.14](#UpdateMembersofaCollection)) or deletes
([section 11.4.15](#DeleteMembersofaCollection)) to members of a collection

### <a name="OData40IntermediateConformanceLevel" href="#OData40IntermediateConformanceLevel">12.1.2 OData 4.0 Intermediate Conformance Level</a>

Expand Down
2 changes: 2 additions & 0 deletions odata-json-format/15 Delta Payload.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ collection.
Changed entities MUST include all available selected properties that
have changed, and MAY include additional properties.

Added or changed entities MAY include [ETags](#ControlInformationetagodataetag).

Entities include control information for selected navigation links based
on [`metadata`](#ControllingtheAmountofControlInformationinResponses).

Expand Down
1 change: 1 addition & 0 deletions odata-protocol/1 Introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Upserts to single-valued non-containment navigation properties|
[Section ##UpdateaComplexProperty]|
Setting a complex property to a different type|
[534](https://github.com/oasis-tcs/odata-specs/issues/534)
[Section ##ReplaceaCollectionofEntities]| Semantics of `continue-on-error` when replacing a collection of entities | [358](https://github.com/oasis-tcs/odata-specs/issues/358)
[Section ##Conformance] | Allow `400 Bad Request` in addition to `501 Not Implemented` for unsupported functionality| [391](https://github.com/oasis-tcs/odata-specs/issues/391)
[Section ##InteroperableODataClients] | Encoding of plus character in URLs | [485](https://github.com/oasis-tcs/odata-specs/issues/485)

Expand Down
4 changes: 4 additions & 0 deletions odata-protocol/11 Data Service Requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -1434,5 +1434,9 @@ A delta payload represents changes to a known state. A delta payload
includes added entities, changed entities, and deleted entities, as well
as a representation of added and removed relationships.

Services that support the use of [ETags](#UseofETagsforAvoidingUpdateConflicts)
for optimistic concurrency control SHOULD return ETag values for added or changed entities
within the delta payload.

Delta payloads can be [requested](#RequestingChanges) from the service
using a delta link or provided as updates to the service.
Loading

0 comments on commit b4c4fcc

Please sign in to comment.