SQL on FHIR WG Meetings
SQL on FHIR WG Meeting — March 28, 2025
Mar 28, 2025

Topics discussed:

  • The group settled on advertising ViewDefinition as a resource type in the CapabilityStatement, so discovery is ordinary FHIR: read the statement, look at the interactions, search for the views. It is against the spec — ViewDefinition isn't a real resource — but the precedent already exists and clients in practice don't fail on resource types they don't recognise. The caveat from the spec side: keep track of what works and what doesn't, because that experience is what should steer the R6 decision, including whether the version has to be explicit.
  • On input, the recommendation was a Parameters resource with a published profile of it. An OperationDefinition can express nearly the same information — it literally reuses the same parameter datatype, parts and all — but you can't validate against it and there are no good examples, so developers end up asking for a profile anyway. A profile can also carry invariants an OperationDefinition can't, like "you may not supply both viewUrl and viewCanonical". R6 adds inputProfile and outputProfile for exactly this; earlier versions need a cross-version extension.
  • A style point that stuck: prefer separate parameter names — viewUrl and viewCanonical — over one polymorphic parameter. Then client code switches on the parameter name, instead of switching on the name and then again on whatever type it discovers.
  • The interesting hole: an operation's return type is a required binding to FHIR types, so there's no way to declare "this returns CSV" or "this returns Parquet". The existing trick, which GraphQL uses, is to declare the return as Binary and lean on the Accept header and mime type. Nobody actually wraps the response in a Binary resource — GraphQL clients would break if you did — so the spec is quietly lying about it. Someone pointed out the Binary page does document exactly this content-negotiation behaviour, which makes it half-defensible. Action: file a ticket to allow declaring a content type directly.
  • On the async export response, bulk export returns 202 with a Location header and a progress value that is just an unstructured string clients try to parse. The proposal is to return a Parameters body as well: an export ID, the location, the input parameters echoed back for debugging, and structured progress — percentage, estimated completion, which views are already exported, rows processed — all optional, since some implementations can't report progress at all. The same shape just accumulates fields as the job runs and ends with the outputs, and it leaves somewhere to put things like an auth hint for fetching the files.