Oracle REST Data Services & Entity Tags

Oracle REST Data Services (ORDS) has always had strong support for generating Entity Tag (ETag) HTTP Headers. Entity Tags are an important aspect of the HTTP protocol, they help reduce needlessly re-transmitting unchanged resources (aka Conditional GET) and they can also be leveraged to provide optimistic locking and thus prevent lost updates.

I recommend reading this post by Joe Gregorio for a detailed explanation of the benefits of generating and using ETags properly.

How ORDS generates ETag Headers

Entity Tag Strategies

Choosing the Entity Tag Strategy in Oracle Application Express


ORDS supports three ways to generate ETag headers:

  • Secure Hash – The bytes of the resource’s headers and body are hashed using a secure digest algorithm, which guarantee’s that anytime a header or the content of the resource changes, it’s ETag header value also changes. This is the default strategy
  • Query – The RESTful Service developer enters an SQL query. Every time a resource changes then the results of this query must also change
  • None – No ETag header is generated for the resource

Trade-offs

Each of these options has different strengths.

  • Secure Hash is the most reliable means for generating an ETag, if the resource or it’s headers change, the ETag is guaranteed to also change.

    Generating the Hash requires examining every byte of the resource’s headers and every byte of it’s body, before the ETag header can be generated. Since HTTP requires that HTTP Headers are sent before the body, this means that the entire contents of the resource must be temporarily buffered while the ETag is computed. For large resources this buffering may noticeably increase latency and increase the amount of RAM required.

    Note that for typical resources, whose size is in the order of hundreds of KBs, this buffering overhead is not significant, and thus using a secure Hash is the sensible default.

  • Sometimes it is possible to design a database table to know exactly when a row in the table changes, for example the table may have a version column or the table may be configured to use row level dependencies.

    In these cases it may be beneficial to use a custom query to generate the ETag. Instead of hashing the entire representation of the resource, ORDS will just hash the results returned from this custom query. ORDS will not need to buffer the entire representation in memory.

    However ORDS will need to perform the additional query to generate the ETag, as well as the query to generate the resource representation.

    For typical resources, the overhead of the network round trip for the additional query is far greater than the overhead for the secure hash. Only for very large resources will the custom query out-perform the secure hash strategy.

    There is also the risk that the custom query does not capture all of the data that may affect the representation of a resource. For example if a resource is composed from multiple rows in a table or rows from multiple tables, then the query must be designed to check the version state of each of those tables and rows. As the design of a resource evolves over time and the query used to generate the resource changes, it is easy to forget to keep the custom ETag query in sync. If this is not done then the ETag value may no longer change everytime the resource changes, and clients will miss updates to the resource, so this strategy may not be as robust as the secure hash strategy.

  • If no ETag is generated, then no buffering is required, but all the benefits of Entity Tags will also be lost.

    The entire resource will be regenerated and retransmitted for each and every request and there will be no means to perform concurrency control on the resource.

Advertisements