Search

ETag

You can enable optimistic concurrency control and caching techniques using ETags.

The default scenario is to use the managed aspect and the modifiedAt field as ETag. To do so, modifiedAt needs to be explicitly added to the model and marked as ETag, as shown in the example:

entity Foo : managed {...}

annotate Foo with {
   modifiedAt @odata.etag;
} 

The advantage of the default scenario is that the modifiedAt field is automatically changed after each data modification.

It is possible to use an arbitrary field as ETag. In this case the developer should provide a new field value after each data modification. The following sample code shows how to use an arbitrary string field for managing the ETags:

entity Foo {
  key ID: UUID;
  externalID: String @odata.etag;
}

The following examples represent typical requests and responses while using ETags:

POST Employees
{ID: 100, name: 'Name'}

201 Created
{'@odata.etag': 'W/"2000-01-01T01:10:10.100Z"',...}
GET Employees(1)
If-Match: "2000-01-01T01:10:10.100Z"

// Employee was not changed
304 Not Modified
GET Employees(1)
If-Match: "2000-01-01T01:10:10.100Z"

// Employee was changed by another user
412 Precondition Failed
UPDATE Employees(1)
If-Match: "2000-01-01T01:10:10.100Z"

// correct ETag and return updated ETag
200 Ok
{'@odata.etag': 'W/"2000-02-02T02:20:20.200Z"',...}

UPDATE Employees(1)
If-Match: "2000-01-01T01:10:10.100Z"

// ETag was changed by the previous update
412 Precondition Failed
DELETE Employees(1)
If-Match: "2000-01-01T01:10:10.100Z"

// ETag was changed
412 Precondition Failed