Today FHIR's http://hl7.org/fhir/async.html defines a request pattern designed for interactions that:
The general interaction pattern is:
$export
scenario, or other interactions that produce a big pile of FHIR resources that clients need to copy wholesale. But other use cases for async aren't a great fit for a Bulk Data Manifest. We want to independently track response status codes, location headers, ETags, resource content, and errors associated with a CRUDS interaction or operation.Observation
s, asynchronously. Allows the server to process incoming results asynchronoulsy, in a queue.
Parameters
resource as the operation output (or a single RiskAssessment
resource, etc).We want a way to take any FHIR CRUDS interaction or operation and apply asynchronous handling. We already have most of the building blocks we need, in the current FHIR Async spec.
In any async interaction, requests for the status endpoint are a way of monitoring progress; an error (e.g., 5xx error) in response to the polling request should not indicate that the underlying CRUDS interaction has failed. It just indicates that polling has failed. We maintain a bright line here: the only way for a client to learn the result of the CRUDS interaction is to evaluate the eventual response once polling has completed.
FHIR's existing async pattern gives us almost everything we need; the only tweak we need to the existing async pattern is, instead of defaulting to a Bulk Data Manifest at the end of the process, we can instead use a batch-response
Bundle containing one single entry; this allows us to represent status codes, locations, etgags, and resource content associated with the CRUDS interaction result. The client looks at Bundle.entry[0].response
to understand the outcome. (Note that for searches, this does eventually produce a search
type Bundle inside the batch-response
Bundle's .entry[0].response
. We don't love Bundles-in-Bundles, but sometimes they happen ;-))
For example, a successful create may eventually lead to:
GET /path/to/status/123
Accept: application/fhir+json
200 OK
Content-type application/fhir+json
{
"resourceType": "Bundle",
"type": "batch-response",
"entry": [{
"response": {
// could say "403"
// if the client is unauthorized, etc, etc,
"status": "200 OK",
"location": "Observation/123"
// additional fields if needed
// * etag
// * lastModified
// * outcome
},
"resource": {
// populated whenever "normal" (synchronous) CRUDS
// interaction would have included a resource in the
// response body -- e.g. if client initially specified
// `Prefer: return=representation`
"resourceType": "Observation",
"id": "123",
// ... snipped for brevity
}
}]
}
$export
, and other operations and searches that return large piles of data?This proposal would not replace the Bulk Data Manifest format, because it's useful in many cases where a client really does want an unordered pile of resources as the output – and because we don't want to break backwards compatibility with existing $export
operations. For $export
, the Bulk Data Manifest would continue to be the default output format; and we could document a common request parameter like _asyncOutputFormat=BulkDataManifest
for searches or custom operations where a client needs to explicitly opt into the Bulk Data Manifest output format on a case-by-case basis.