Aidbox Docs

ETAG support

The ETag HTTP response header is a unique identifier assigned to a specific version of a resource on a server. When a resource, like a web page or an API endpoint, changes, its ETag also changes. This mechanism allows client-side caching and efficient revalidation.

When a client requests a resource, it may include the ETag it has in an If-None-Match request header. If the server's current version of the resource has a matching ETag, it means the content hasn't changed, and the server can send back a 304 Not Modified response without the actual resource data.

This saves bandwidth and speeds up the loading process, as the client can use its cached version. When the ETags don't match, it indicates the resource has changed, prompting the server to send the new version of the resource with its updated ETag.

Aidbox ETags mechanism is based on the txid column of the resource table in the database. If you update resources directly in the database, don't forget to update the txid column: UPDATE resource SET txid = nextval('transaction_id_seq')

Examples

Revalidate a resource you already have (If-None-Match304)

When a resource is updated, GET /fhir/<resourceType>/<id> returns the new version. To cheaply check whether a version you already hold is still current, send its versionId in the If-None-Match header:

GET /fhir/Patient/<id>
Accept: application/json
If-None-Match: W/"<versionId you remember>"

If the version is unchanged you get 304 Not Modified with no body (this still reads the resource from the database — the saving is network bandwidth, not database load). If it changed, you get 200 OK with the new resource and its updated ETag. Both W/"138" and the bare 138 are accepted.

Optimistic locking on update (If-Match412)

To prevent lost updates when several writers touch the same resource, send the version your change is based on in the If-Match header:

PUT /fhir/Patient/<id>
Content-Type: application/json
If-Match: W/"<versionId you read>"

{ ...resource... }

If the stored version still matches, the update proceeds. If it changed in the meantime, Aidbox returns 412 Precondition Failed, so you can re-read and retry instead of silently overwriting.

ETag Cache

The ETag cache described in this section was removed in Aidbox 2208 (August 2022).

ETag / txid values are now read directly from the database per request, so there is no cache to maintain, build, or reset. The DELETE /$etags-cache and DELETE /<ResourceType>/$etags-cache endpoints are deprecated and only return a Deprecated! message. A plain GET with If-None-Match always reads the resource from the database before returning 304 Not Modified — the saving is network bandwidth, not database load.

This section is kept for historical reference only.

Historically, all ETag values were cached to make ETag queries efficient. If the cache became invalid, it could be reset with DELETE /$etags-cache or DELETE /Patient/$etags-cache.

To build the cache for a specific resourceType, Aidbox ran a query to get the max value of the txid column. To make this operation efficient, it was recommended to build an index on the txid column for tables where ETag was used:

CREATE INDEX IF NOT EXISTS <resourceType>_txid_btree ON <resourceType> using btree(txid);

CREATE INDEX IF NOT EXISTS <resourceType>_history_txid_btree ON <resourceType>_history using btree(txid);

replace with table name, for example CREATE INDEX IF NOT EXISTS patient_txid_btree ON patient using btree(txid); CREATE INDEX IF NOT EXISTS patient_history_txid_btree ON patient_history using btree(txid);

Last updated: