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:

  1. Query one or more business object items and, for each returned resource item, obtain the ETag value from the changeIndicator property in the properties 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 the properties 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"
      } ]
    }
    
  2. 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:

  1. Query one or more business object items and, for each returned resource item, obtain the ETag value from the changeIndicator property in the properties 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 the properties 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"
      } ]
    }
    
  2. 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"
        } ]
    }