Fhir Rest Notes

Conditional Read: If-None-Match and the Caching Wins It Enables

Every FHIR client that polls a resource is a client that will benefit from conditional read. The pattern is simple, the wins are large, and the number of client teams that never wire it up is uncomfortably high. If your Patient poll pulls the same full resource every fifteen seconds, most of that bandwidth is wasted.

The site's FHIR RESTful API cheatsheet has the headers laid out. For the broader REST context, more on healthcare interoperability collects related pieces.

The Header Pair That Does the Work

Every FHIR resource comes back with an ETag header that carries the version identifier. The client stashes that ETag. Next request, the client sends If-None-Match with the same ETag value. If the resource has not changed, the server responds with 304 Not Modified and no body. If it has changed, the server responds with 200 and the updated resource plus a new ETag.

Two headers, one round trip, no payload on the unchanged case. That is the entire mechanic.

Why the Bandwidth Win Actually Matters

A Patient resource with sixteen extensions, three identifiers, and a photo attachment is not a small payload. Multiply that by five thousand active patients polled at the two-minute cadence typical for a nurse dashboard, and the bandwidth adds up faster than teams expect. Conditional read cuts most of that to header-only responses.

Server operators care because bandwidth costs less than compute, and 304 responses do not serialize the resource. Client operators care because a 304 is faster and the request budget stays within reason.

The If-Modified-Since Cousin

If-Modified-Since is the time-based variant. It works the same way but keys off Last-Modified. The two are interchangeable in principle, but ETag is the FHIR-preferred convention because version identifiers are stable across clock skew and time-based ambiguity.

Use If-None-Match when the server exposes ETag, which is essentially always. Reserve If-Modified-Since for the rare server that omits ETag.

When Conditional Read Fails Quietly

Two failure modes eat the win:

  • The server does not honor the header and returns 200 with a body every time
  • The client caches the ETag but drops it on a new session

The first is a server bug. The second is a client design mistake — the ETag has to survive whatever request cycle the client uses. Both are common enough that teams should test conditional read specifically, not assume it works.

Combine With Conditional Update

The paired win is on the write side. Sending the same ETag back as If-Match on a PUT gives you optimistic concurrency for free. The server rejects the update with 412 Precondition Failed if the resource changed underneath, and the client can then re-read and retry. For the write side, conditional update: preventing lost writes without pessimistic locking walks through the pattern.

Where the Cheatsheet Fits

An interactive cheatsheet lives at the FHIR RESTful API cheatsheet with every conditional verb annotated. If your client team is still copying the header names into ad hoc code, the cheatsheet is what to link them to.

The Short Version

Conditional read is the single highest-leverage FHIR REST feature that most clients ignore. Stash the ETag on read, send If-None-Match on the next request, and the poll cost drops. Then combine it with conditional update for lost-write protection, and the client survives concurrent editors without a lock service.

For the wider picture of the verbs that differ from vanilla REST, the FHIR REST verbs that actually differ from vanilla REST is the entry, and designing a FHIR client that survives the tricky verbs is where it lands.

Chalk-blackboard diagram of a conditional read cycle with client sending If-None-Match, server returning 304 or 200 with a new ETag, drawn as white chalk sketches with pastel accents on slate

Sources