5 Data Consistency Tasks
You can perform data consistency checks while making REST API calls. This capability uses version history in the database to enable you to manage HTTP payloads according to updates in the resource itself.
About Data Consistency
REST APIs support checking for data consistency when updating or retrieving a resource item. Data consistency is enforced by the REST API by generating an entity tag (ETag) with precondition headers so that the resource item matches the server side resource state before updating or retrieving.
REST APIs support generating an entity tag (ETag) in the response header when the requested resource item has data consistency check enabled.
When your visual development tool supports entity change indicators (as it is, for example, in Oracle Visual Builder), the REST API will assign a unique value to indicate the state of each resource item on the server side. At runtime, when the business object item underlying the server side resource item changes, the REST API assigns a new state value to the ETag. The following header shows the ETag returned with a request to retrieve a Department
resource item.
HTTP/1.1 200 OK Cache-Control: no-cache, no-store, must-revalidate Location: Content-Length: 1069 Content-Type: application/json ETag: "ACED00057372037200136261636C6520136261636C65237200136261636C652" Link: <base_url>/Department/10>;rel="self";kind="item";name="Department"
The web application request can use the ETag value returned in the header response of each resource item to create subsequent requests that contain precondition headers (If-Match
/If-None-Match
). Based on the specified ETag and the precondition, the server will evaluate the current resource item state and match against the provided ETag. If the precondition is satisfied, the requested operation is executed; otherwise, a 412
error is returned. The error payload will contain the current resource item in the server side and the header will also reflect the current ETag value.
To support testing ETag values, the REST API provides the following precondition header fields. Usage of these precondition fields forces the REST API to compare a supplied ETag value against the ETag values of previously requested items.
-
Verify that the client is providing a state (obtained from a previous resource item response) that matches the current state on the server:
If-Match: "
<ETag value from resource item response>
" -
Verify that the client is providing a state (obtained from a previous resource item response) that does not match the current state on the server.
If-None-Match: "
<ETag value from resource item response>
"
The following are typical use cases when checking for data consistency:
-
Check that the business object item matches the server side resource item state before updating
-
Retrieve the business object item using the server side resource item state when none of the requested items match any previously requested items
While these use cases involve GET and PATCH methods, the precondition header and ETag value can be used to check that any HTTP method operation will be applied to the current state of the business object item.
When retrieving a resource collection, an additional custom property changeIndicator
will appear in the response payload of resource with data consistency enabled. This property contains the current ETag value of each resource item in the requested collection. The following sample illustrates the changeIndicator
property in the links
section of a Department
resource collection. The presence of ETag values in the resource collection payload is a convenience for the web application that can reduce the number of requests to obtain the ETag from individual resource items.
{ "items" : [ { "DepartmentId" : 10, "DepartmentName" : "Administration", "RelState" : 1, "links" : [ { "rel" : "self", "href" : "<base_url>/Department/10", "name" : "Department", "kind" : "item", "properties" : { "changeIndicator" : "ACED0005737200136A6176612E7574696C2E41727261794C69737 47881D21D99C7619D03000149000473697A65787000000001770400000001737200186F721 636C652E6A626F2E646F6D61696E2E4E7564A362286F0200015B0004646174617400025B45 27870757200025B42ACF317F8060854E00200007870" } "links" : [ { "rel" : "self", "href" : "<base_url>/Department/10", "name" : "Department", "kind" : "item", }, { "rel" : "child", "href" : "<base_url>/Department/10/child/Employee", "name" : "Employee", "kind" : "collection", } ] }, { "DepartmentId" : 20, "DepartmentName" : "Marketing", "links" : [ { "rel" : "self", "href" : "<base_url>/Department/20", "name" : "Department", "kind" : "item", "properties" : { "changeIndicator" : "ACED0005737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A65787000000001770400000001737200186F7261636C652E6A626F2E646F6D61696E2E4E756D626572A5B1371914E0BFDA0200014900096D48617368436F6465787200116F7261636C652E73716C2E4E554D424552E90466EE632BE1D5020000787200106F7261636C652E73716C2E446174756D4078F514A362286F0200015B0004646174617400025B427870757200025B42ACF317F8060854E0020000787000000002C10A0000000078" } }, { "rel" : "child", "href" : "<base_url>/Department/20/child/Employee", "name" : "Employee", "kind" : "collection" } ] }, { ... } ] } ], "count" : 5, "hasMore" : true, "limit" : 25, "offset" : 0, "links" : [ { "rel" : "self", "href" : "<base_url>/Department", "name" : "Department", "kind" : "collection" } ] }
Checking for Data Consistency When Updating Business Object Items
REST APIs support checking for data consistency when updating resource items.
To check for data consistency using the ETag header and conditional header fields:
-
Query one or more business object items and, for each returned resource item, obtain the ETag value from the
changeIndicator
property in theproperties
section of the response. When querying multiple business object items, there will not be a single ETag response header. Instead, the ETag for each of the items in the response will be in theproperties
section.HTTP/1.1 200 OK Cache-Control: no-cache, no-store, must-revalidate Location: Content-Length: 861 Content-Type: application/json ETag: "responseETag123" Link: <<base_url>/Department/10>;rel="self";kind="item";name="Department" Set-Cookie: JSESSIONID=jXvsJ1GpdkFJV5Jh0yk7D72vPZ42t8tLYDg74NRKFQzXdnsjG9vv!1113104013; path=/; HttpOnly X-ORACLE-DMS-ECID: 51f1ff4535af720c:-7e156247:148ec9eeb3b:-8000-00000000000001ad X-Powered-By: Servlet/2.5 JSP/2.1 { "DepartmentId" : 10, "DepartmentName" : "Administration", "links" : [ { "rel" : "self", "href" : "<base_url>/Department/10", "name" : "Department", "kind" : "item", "properties" : { "changeIndicator" : "responseETag123" } }, { "rel" : "child", "href" : "<base_url>/Department/10/child/Employee", "name" : "Employee", "kind" : "collection" } ] }
-
Update the business object item, using a PATCH request and check for data consistency by supplying the following conditional header field:
-
If-Match: "
<ETag value from resource item response>
"
to verify that the state of a requested resource item is current with the previous resource item response.
-
The following sample updates the DepartmentName
field of department 10
when the If-Match
precondition test is satisfied. In the first request (Request 1), the ETag value responseETag123
is identical to the ETag of the current department 10
on the server side, indicating that the state of the resource item is consistent with the server side. Consequently, the update to DepartmentName
is allowed.
In the subsequent request (Request 2), however, the ETag supplied in the If-Match
precondition is unchanged and no longer matches the new ETag value the server has for department 10
resource item. As a consequence of the stale ETag value used in the second request, the update fails with an HTTP code 412
, indicating the precondition test failed, and the current ETag value responseETag567
is returned in the response header. This occurs in production web applications when multiple users simultaneously access the same business object item. For example, when user 1 and user 2 both query the same item, the item has, for example, ETag value 1. Then, if user 1 successfully updates the item with ETag value 1, and user 2 attempts to update the same item with ETag value 1, the attempt will fail.
Request 1
-
URL 1
<base_url>/Department/10
-
HTTP Method
PATCH
-
Precondition 1
If-Match: "responseETag123"
-
Content-Type
application/vnd.oracle.adf.resourceitem+json
-
Payload 1
{ "DepartmentName" : "FirstAttempt_NewDepartmentName" }
Response 1
-
HTTP Code
200
-
Content-Type
application/vnd.oracle.adf.resourceitem+json
-
ETag
responseETag567
-
Payload 1
{ "DepartmentId" : 10, "DepartmentName" : "FirstAttempt_NewDepartmentName", "RelState" : null, "links" : [ { "rel" : "self", "href" : "<base_url>/Department/10", "name" : "Department", "kind" : "item", "properties" : { "changeIndicator" : "responseETag567" } }, { "rel" : "child", "href" : "<base_url>/Department/10/child/Employee", "name" : "Employee", "kind" : "collection" } ] }
Request 2
-
URL 2
<base_url>/Department/10
-
HTTP Method
PATCH
-
Precondition 2
If-Match: "staleETag789"
-
Content-Type
application/vnd.oracle.adf.resourceitem+json
-
Payload 2
{ "DepartmentName" : "SecondAttempt_NewDepartmentName" }
Response 2
-
HTTP Code
412
(Precondition failed) -
Content-Type
application/vnd.oracle.adf.resourceitem+json
-
ETag
responseETag567
-
Payload 2
{ "DepartmentId" : 10, "DepartmentName" : "FirstAttempt_NewDepartmentName", "RelState" : null, "links" : [ { "rel" : "self", "href" : "<base_url>/Department/10", "name" : "Department", "kind" : "item", "properties" : { "changeIndicator" : "responseETag567" } }, { "rel" : "child", "href" : "<base_url>/Department/10/child/Employee", "name" : "Employee", "kind" : "collection" } ] }
Checking for Data Consistency When Retrieving Business Object Items
REST APIs support checking for data consistency when retrieving resource items.
To check for data consistency using the ETag header and conditional header fields:
-
Query one or more business object items and, for each returned resource item, obtain the ETag value from the
changeIndicator
property in theproperties
section of the response. When querying multiple business object items, there will not be a single ETag response header. Instead, the ETag for each of the items in the response will be in theproperties
section.HTTP/1.1 200 OK Cache-Control: no-cache, no-store, must-revalidate Location: Content-Length: 861 Content-Type: application/json ETag: "responseETag123" Link: <base_url>/Department/10>;rel="self";kind="item";name="Department" Set-Cookie: JSESSIONID=jXvsJ1GpdkFJV5Jh0yk7D72vPZ42t8tLYDg74NRKFQzXdnsjG9vv!1113104013; path=/; HttpOnly X-ORACLE-DMS-ECID: 51f1ff4535af720c:-7e156247:148ec9eeb3b:-8000-00000000000001ad X-Powered-By: Servlet/2.5 JSP/2.1 { "DepartmentId" : 10, "DepartmentName" : "Administration", "links" : [ { "rel" : "self", "href" : "<base_url>/Department/10", "name" : "Department", "kind" : "item", "properties" : { "changeIndicator" : "responseETag123" } }, { "rel" : "child", "href" : "<base_url>/Department/10/child/Employee", "name" : "Employee", "kind" : "collection" } ] }
-
Query one or more business object items and check for data consistency by supplying the following conditional header field:
-
If-None-Match: "
<ETag value from resource item response>
"
to verify that the state of none of the previously requested resource items is current with the resource item request.
-
The following sample retrieves department 10
when the If-None-Match
precondition test is satisfied. In the first request (Request 1), the ETag value responseETag123
matches the ETag of the previously requested Department 10
resource item on the server side, indicating that the state of the resource item is consistent with the server side. Consequently, the precondition fails and there is no need to return a newer department 10
resource item. The request returns with an HTTP code 304
, indicating the state on the server has not been modified.
In the subsequent request (Request 2), however, the ETag unmatchedETagXYZ
supplied in the If-None-Match
precondition does not exist on the server. As a consequence, the precondition succeeds and department 10
is retrieved. The request returns an HTTP code 200
, indicating the state had changed, and the current (unchanged) ETag value responseETag123
is returned in the response header.
Request 1
-
URL 1
<base_url>/Department/10
-
HTTP Method
GET
-
Precondition 1
If-None-Match: "responseETag123"
-
Content-Type
none
-
Payload
none
Response 1
-
HTTP Code
304
state not modified -
Content-Type
none
-
Payload 1
none
Request 2
-
URL 2
<base_url>/Department/10
-
HTTP Method
GET
-
Precondition 2
If-None-Match: "unmatchedETagXYZ"
-
Content-Type
none
-
Payload
none
Response 2
-
HTTP Code
200
-
Content-Type
application/vnd.oracle.adf.resourceitem+json
-
ETag
responseETag123
-
Payload 2
{ "DepartmentId" : 10, "DepartmentName" : "Administration", "RelState" : null, "links" : [ { "rel" : "self", "href" : "<base_url>/Department/10", "name" : "Department", "kind" : "item", "properties" : { "changeIndicator" : "responseETag123" } }, { "rel" : "child", "href" : "<base_url>/Department/10/child/Employee", "name" : "Employee", "kind" : "collection" } ] }