R6 Ballot (2nd Draft)

Publish-box (todo)

FHIR Infrastructure icon Work Group Maturity Level: 4 Standards Status: Draft

All of the interactions defined in the RESTful API are described as synchronous operations - that is, the client makes a query and waits for the server to respond with the outcome in the HTTP response. This pattern is not always suitable when substantial amounts of data must be returned.

A good example of this is the $export operation icon, where simple searches may result in large amounts of data.

The asynchronous request pattern, based on rfc 7240 icon, caters to this use case and is applicable for for use in Operations and Defined Interactions interactions. Servers may choose which interactions the pattern should be supported on (if at all).

For use cases that return small amounts of data but may take a lot of time to process, see Asynchronous Interaction Request.

The request will support the HTTP methods, URLs, headers and other parameters that normally apply, but servers SHALL also support the Prefer header described below, and SHOULD support the Accept header and _outputFormat parameter described below.

  • Accept (string)

    Specifies the format of the optional OperationOutcome Resource response to the kick-off request. A client SHOULD provide this header. A server may support any subset of the Serialization Format Representations. If omitted, the server MAY return an error or MAY process the request and return a format selected by the server.

  • Prefer (string, required)

    Specifies whether the response is immediate or asynchronous. Setting this to respond-async triggers this async pattern.

  • _outputFormat (string, optional, defaults to application/fhir+ndjson)

    The format for the generated bulk data files. Currently, ndjson icon must be supported, though servers may choose to also support other output formats. Servers SHALL support the full content type of application/fhir+ndjson as well as abbreviated representations including application/ndjson and ndjson.

    For requests types where the server supports either the Asynchronous Bulk Data Request pattern or the Asynchronous Interaction Request pattern, requests that include the _outputFormat parameter SHALL trigger the Asynchronous Bulk Data Request pattern.

  • HTTP Status Code of 202 Accepted
  • Content-Location header with the absolute URL of an endpoint for subsequent status requests (polling location)
  • Optionally, a OperationOutcome Resource in the body

After a Bulk Data request has been started, a client MAY send a http DELETE request to the URL provided in the Content-Location header to cancel the request. If the request has been completed, a server MAY use the request as a signal that a client is done retrieving files and that it is safe for the sever to remove those from storage. Following the delete request, when subsequent requests are made to the polling location, the server SHALL return a 404 Not Found error and an associated OperationOutcome Resource.

  • HTTP Status Code of 202 Accepted
  • Optionally a FHIR OperationOutcome in the body

After a Bulk Data request has been started, the client MAY poll the status URL provided in the Content-Location header by issuing HTTP GET requests to the location.

A client SHOULD follow an exponential backoff icon approach when polling for status. A server SHOULD supply a Retry-After icon header with a with a delay time in seconds (e.g., 120 to represent two minutes) or a http-date (e.g., Fri, 31 Dec 1999 23:59:59 GMT). When provided, a client SHOULD use this information to inform the timing of future polling requests. The server SHOULD keep an accounting of status queries received from a given client, and if a client is polling too frequently, the server SHOULD respond with a 429 Too Many Requests status code in addition to a Retry-After header, and optionally a OperationOutcome Resource with further explanation. If excessively frequent status queries persist, the server MAY return a 429 Too Many Requests status code without returning a status answer. It may either return a Retry-after header with the 429 indicating the amount of time that needs to pass before it will again respond to a status check, or it may choose to abandon the asynchronous operation entirely and force a retry. Other standard HTTP 4XX as well as 5XX status codes may be used to identify errors as mentioned.

When requesting status, the client SHOULD use an Accept header indicating a content type of application/json. In the case that errors prevent the asynchronous operation from completing, the server SHOULD respond with a OperationOutcome Resource in JSON format.

  • HTTP Status Code of 202 Accepted
  • Optionally an X-Progress header with a text description of the status of the request that is less than 100 characters. The format of this description is at the server's discretion and MAY be a percentage complete value, or MAY be a more general status such as "in progress". The client MAY parse the description, display it to the user, or log it.
  • HTTP status code of 4XX or 5XX
  • Content-Type header of application/fhir+json when body is a OperationOutcome Resource
  • The body of the response SHOULD be a OperationOutcome Resource in JSON format. If this is not possible (for example, the infrastructure layer returning the error is not FHIR aware), the server MAY return an error message in another format and include a corresponding value for the Content-Type header.

In the case of a polling failure that does not indicate failure of the original request, a server SHOULD use a transient code from the IssueType valueset when populating the OperationOutcome Resource issue.code element to indicate to the client that it should retry the request at a later time.

Note: Even if some of the requested resources cannot successfully be returned, the overall request MAY still succeed. In this case, the Response.error array of the completion response body SHALL be populated with one or more files in ndjson format containing OperationOutcome Resources to indicate what went wrong (see below). In the case of a partial success, the server SHALL use a 200 status code instead of 4XX or 5XX. The choice of when to determine that a job has failed in its entirety (error status) vs. returning a partial success (complete status) is left up to the server implementer.

  • HTTP status of 200 OK
  • Content-Type header of application/json
  • The server SHOULD return an Expires header indicating when the files listed will no longer be available for access.
  • A body containing a JSON object providing metadata, and links to the generated Bulk Data files. The files SHALL be accessible to the client at the URLs advertised. These URLs MAY be served by file servers other than a FHIR-specific server.

Fields:

Field Optionality Type Description
transactionTime required FHIR instant Indicates the server's time when the query is run. The response SHOULD NOT include any resources modified after this instant, and SHALL include any matching resources modified up to and including this instant.

Note: To properly meet these constraints, a FHIR server might need to wait for any pending transactions to resolve in its database before starting the asynchronous operation process.
request required String The full URL of the original kick-off request. In the case of a HTTP POST request, this URL will not include the request parameters. Note: this field may be removed in a future version.
requiresAccessToken required Boolean Indicates whether downloading the generated files requires the same authorization mechanism as kick-off and status requests.

Value SHALL be true if both the file server and the FHIR API server control access using OAuth 2.0 bearer tokens. Value MAY be false for file servers that use access-control schemes other than OAuth 2.0 or provide output file URLs that are "capability URLs" (e.g., short-lived high-entropy URLs that can be dereferenced without additional authentication).
output required JSON array An array of file items with one entry for each generated file. If no resources are returned from the kick-off request, the server SHOULD return an empty array.

Each file item SHALL contain the following fields:

- type - the FHIR resource type that is contained in the file.

Each file SHALL contain resources of only one type, but a server MAY create more than one file for each resource type returned. The number of resources contained in a file MAY vary between servers. If no data are found for a resource, the server SHOULD NOT return an output item for that resource in the response. These rules apply only to top-level resources within the response; as always in FHIR, any resource MAY have a "contained" array that includes referenced resources of other types.

- url - the absolute path to the file. The format of the file SHOULD reflect that requested in the _outputFormat parameter of the initial kick-off request.

Each file item MAY optionally contain the following field:

- count - the number of resources in the file, represented as a JSON number.
deleted optional JSON array An array of deleted file items following the same structure as the output array.

The ability to convey deleted resources is important in cases when a server may have previously returned data and wishes to indicate that these data should be removed from downstream systems. When a timestamp parameter such as _since is supported by the request type and supplied in the kick-off request, this array SHOULD be populated with output files containing FHIR Transaction Bundles that indicate which FHIR resources match the kick-off request criteria, but have been deleted subsequent to the timestamp. If no resources have been deleted, or the timestamp parameter was not supplied, or the server has other reasons to avoid exposing these data, the server MAY omit this key or MAY return an empty array. Resources that appear in the 'deleted' section of a manifest SHALL NOT appear in the 'output' section of the manifest.

Each line in the output file SHALL contain a FHIR Bundle with a type of transaction which SHALL contain one or more entry items that reflect a deleted resource. In each entry, the request.url and request.method elements SHALL be populated. The request.method element SHALL be set to DELETE.

Example deleted resource bundle (represents one line in output file):
{
 "resourceType": "Bundle",
 "id": "bundle-transaction",
 "meta": {"lastUpdated: "2020-04-27T02:56:00Z},
 "type": "transaction",
 "entry":[{
  "request": {"method": "DELETE", "url": "Patient/123"}
  ...
 }]
}
error required Array Array of message file items following the same structure as the output array.

Error, warning, and information messages related to the asynchronous operation SHOULD be included here (not in output). If there are no relevant messages, the server SHOULD return an empty array. Only the FHIR OperationOutcome resource type is currently supported, so the server SHALL generate files in the same format as Bulk Data output files that contain FHIR OperationOutcome resources.

If the request contained invalid or unsupported parameters along with a Prefer: handling=lenient header and the server processed the request, the server SHOULD include a FHIR OperationOutcome resource for each of these parameters.

Note: this field may be renamed in a future version of this specification to reflect the inclusion of FHIR OperationOutcome resources with severity levels other than error.
extension optional JSON object Server implementations may use the extension field to provide custom behavior and information. For example, a server may choose to provide a custom extension that contains a decryption key for encrypted ndjson files. The value of an extension element SHALL be a pre-coordinated JSON object.

Note: In addition to extensions being supported on the root object level, extensions may also be included within the fields above (e.g., in the 'output' object).

Example response body:

{
  "transactionTime": "2021-01-01T00:00:00Z",
  "request" : "https://example.com/fhir/Patient/$export?_type=Patient,Observation",
  "requiresAccessToken" : true,
  "output" : [{
    "type" : "Patient",
    "url" : "https://example.com/output/patient_file_1.ndjson"
  },{
    "type" : "Patient",
    "url" : "https://example.com/output/patient_file_2.ndjson"
  },{
    "type" : "Observation",
    "url" : "https://example.com/output/observation_file_1.ndjson"
  }],
  "deleted": [{
    "type" : "Bundle",
    "url" : "https://example.com/output/del_file_1.ndjson"      
  }],
  "error" : [{
    "type" : "OperationOutcome",
    "url" : "https://example.com/output/err_file_1.ndjson"
  }],
  "extension":{"https://example.com/extra-property": true}
}

Using the URLs supplied by the FHIR server in the Complete Status response body, a client MAY download the generated Bulk Data files (one or more per resource type) within the time period specified in the Expires header (if present). If the requiresAccessToken field in the Complete Status body is set to true, the request SHALL include a valid access token.

As long as servers are following relevant security guidance, they MAY choose to generate output manifests where requiresAccessToken is true or false; this applies even for servers available on the public internet. When requiresAccessToken is set to false and no additional authorization-related extensions are present on the completion manifest's output entry, then the output URLs SHALL be dereferenceable directly, and SHALL be short lived following the expiration timing requirement that have been documented for bearer tokens in the SMART Backend Services Authorization Guide icon. In this case, a client MAY re-fetch the output manifest if output links have expired and MAY use the Expires header on the output response, when present, as a hint to know when capability URLs will expire.

The output data SHALL include only the most recent version of any FHIR resources unless the client explicitly requests different behavior in a fashion supported by the server (e.g., via a new query parameter yet to be defined). Inclusion of the Resource.meta information in the resources is at the discretion of the server (as it is for all FHIR interactions).

References in the resources returned MAY be relative URLs with the format resourceType/id, or MAY be absolute URLs with the same structure rooted in the base URL for the server from which the asynchronous operation was performed.

Example NDJSON output file:

{"resourceType":"Patient","id":"5c41cecf-cf81-434f-9da7-e24e5a99dbc2","name":[{"given":["Brenda"],"family":["Jackson"]}],"gender":"female","birthDate":"1956-10-14T00:00:00.000Z"}
{"resourceType":"Patient","id":"3fabcb98-0995-447d-a03f-314d202b32f4","name":[{"given":["Bram"],"family":["Sandeep"]}],"gender":"male","birthDate":"1994-11-01T00:00:00.000Z"}
{"resourceType":"Patient","id":"945e5c7f-504b-43bd-9562-a2ef82c244b2","name":[{"given":["Sandy"],"family":["Hamlin"]}],"gender":"female","birthDate":"1988-01-24T00:00:00.000Z"}
  • Accept (optional, defaults to application/fhir+ndjson)

Specifies the format of the file being requested.

  • HTTP status of 200 OK
  • Content-Type header that matches the file format being delivered. For files in ndjson format, SHALL be application/fhir+ndjson
  • Body of FHIR resources in newline delimited json - ndjson icon or other requested format
  • HTTP Status Code of 4XX or 5XX

If resources in an output file contain elements of the type Attachment, the server SHOULD populate the Attachment.contentType code as well as either the data element or the url element. When populated, the url element SHALL be an absolute url that can be de-referenced to the attachment’s content.

When the url element is populated with an absolute URL and the requiresAccessToken field in the Complete Status body is set to true, the url location must be accessible by a client with a valid access token, and SHALL NOT require the use of additional authentication credentials. When the url element is populated and the requiresAccessToken field in the Complete Status body is set to false and no additional authorization-related extensions are present on a the Complete Status body's output entry, the url location SHALL be dereferenceable directly, and SHALL be short lived following the expiration timing requirement that have been documented for bearer tokens in the SMART Backend Services Authorization Guide icon.

Note that if a server copies files to the Bulk Data output endpoint or proxies requests to facilitate access from this endpoint, it may need to modify the Attachment.url element when generating the Bulk Data output files.