'Why make a client fetch the result just to find out the job failed?' — Nov 4, 2025
The motivation
Two async patterns today — the legacy bulk export, and one documented in the spec that essentially nobody uses — and the documented one insists you respond with a Bundle, which doesn't suit a read that ought to return a resource, or an operation that ought to return Parameters.
The goal: a generic pattern so any operation can be turned async, perhaps flagged in the OperationDefinition.
The one thing we definitely don't want is to produce a fifth pattern.
The disagreement — one extra request
In Josh's draft, polling always answers 200 with a location; if the job failed, you only discover that after you fetch the result location. The justification: it lets you tell a polling error apart from a job error.
Nikolai isn't convinced the extra round trip earns that.
If I already knew the job had failed, why send them fishing — I'd say so in the status.
Steve noted bulk data export hands back a bundle with a collection of successes and a collection of failures, and that sometimes it's simply nice to be told everything is fine rather than sift a big bundle to find out.
John also corrected a piece of the record: the claim that only one implementer uses the spec's existing async pattern isn't right — his side implemented it as a reusable piece and then offered it on everything, so this lands on top of something already in production.
Naming parameters in a SQL query — no standard answer
- JDBC uses positional question marks
- Oracle-ish style uses
:name - C# world uses
@name - Some use
{0}/{1}, both of which force you to keep the ordering straight
Colon is awkward because SQL constructs contain colons, so Nikolai floated handlebars as safest.
You need a parser regardless, because whatever symbol you pick can also appear inside a string literal.
On table names specifically, John argued they must be distinguishable from ordinary parameters because you treat them differently — you go looking for them as a table.
Arjun questioned why the table name needs to be dynamic at all; Nikolai's reason: in most systems it isn't the real table name anyway, and might be another schema or a URL in a bucket.
Two problems with repeat
- The FHIRPath expression in the spec is simply wrong —
repeatreturns a collection of strings and the count counts all of it, so it breaks as soon as there are two.existsoranyTruewere floated as the fix - Implementers got
repeatworking via a common table expression — runs in Postgres, slowly. Nikolai wants to try Postgres JSON path with its recursive wildcard instead, which won't port but would prove the optimisation is there
John's open worry: whether any engine the group cares about lacks CTEs.
On Gene's CQL-to-SQL converter
Nikolai's advice: split it into pieces and bank the valuable part first — reusing the clinical reasoning infrastructure to calculate measures over ViewDefinitions and queries, without any translation at all, is already interesting on its own.
The translation itself is a great adventure. I've watched people translate to C for years and they're still mid-journey. I tried it twice — never got it automated, and by hand always ended up writing something more efficient.
Which leaves the real question: how you prove the SQL means the same thing as the CQL. His answer: test datasets with expected results, so it stops mattering whether a human or a machine did the translating.
John's human-in-the-loop angle: what hooks does the tool give an author to review and feed back, so it augments rather than replaces?