This page explains how to manage FHIR resources by executing FHIR bundles, which are a collection of FHIR resources and operations to perform on those FHIR resources.
The
ExecuteBundle
method implements the FHIR standard batch/transaction interaction
(DSTU2,
STU3,
and R4) and history operations.
FHIR bundles
A FHIR bundle contains an array of entries, each of which represents an operation, such as create, update, or delete, on a resource, such as an Observation or a Patient. See the detailed descriptions for the elements in the Bundle resource.
When you execute a FHIR bundle, the bundle type determines how the operations in the bundle are performed. The following bundle types are available:
batch
: executes the operations as multiple independent requests.transaction
: executes the operations as multiple requests that depend on one another.history
: inserts the entries into a resource's history.
For example, suppose that a transaction bundle includes creating a Patient resource and an Observation resource. If the Patient resource creation request fails, then the Observation resource is not created.
If an operation fails when the bundle type is batch
, the
Cloud Healthcare API executes the remaining operations in the bundle. If an
operation fails when the bundle type is transaction
, the
Cloud Healthcare API stops executing operations and rolls back the
transaction.
History bundles
History bundles are custom extensions to the FHIR standard that support backup and restore use cases, such as synchronization. You can use history bundles to insert or replace resource versions in a FHIR resource's history. You can only remove resource versions using the
Resource-purge
method. The history
bundle is executed as a single transaction with a limit
of 100 entries per bundle. If a resource version in the history
bundle has a
timestamp greater than the latest version in the FHIR store, then the
latest version will be updated accordingly. If the history
bundle is inserted
successfully, an empty response is returned, otherwise an OperationOutcome
is
returned describing the failure.
Support for history bundles isn't enabled by default. A FHIR store administrator must
set enableHistoryModifications
to true
on the
FHIR store configuration.
You can't use history bundles if disableResourceVersioning
is
set to true
on the FHIR store configuration.
History bundles are provided in the same format in which they are returned from the
fhir.history
method. To be valid, each bundle entry requires a resource ID, modification timestamp, and
status. Additionally, all entries must have the same resource ID. The
resource ID is provided with the resource.id
field or the request.url
field. If fields are provided, the provided resource ID be the same. The resource timestamp is provided
with the meta.lastUpdated
field in the resource or the
response.lastModified
field.
Granting permissions for executing bundles
The datasets.fhirStores.fhir.executeBundle
permission role is required to
execute bundles. To grant this permission, use the
healthcare.fhirResourceReader
role. For the steps to grant this permission,
see Modifying a policy.
To execute history bundles, the datasets.fhirStores.fhir.import
permission role is also required.
The Cloud Healthcare API checks permissions for each operation in the bundle.
If you have healthcare.fhirResources.create
permission but not
healthcare.fhirResources.update
permission, you can only execute bundles
containing healthcare.fhirResources.create
operations.
Executing a bundle
To execute a FHIR bundle, use the
projects.locations.datasets.fhirStores.fhir.executeBundle
method.
In the following samples, BUNDLE.json is the path and filename to a JSON-encoded FHIR bundle. You can also include the bundle in the request body.
The following sample Bundle creates a Patient resource and deletes another Patient resource:
{
"resourceType": "Bundle",
"id": "bundle-transaction",
"meta": {
"lastUpdated": "2018-03-11T11:22:16Z"
},
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "Patient",
"name": [
{
"family": "Smith",
"given": [
"Darcy"
]
}
],
"gender": "female",
"address": [
{
"line": [
"123 Main St."
],
"city": "Anycity",
"state": "CA",
"postalCode": "12345"
}
]
},
"request": {
"method": "POST",
"url": "Patient"
}
},
{
"request": {
"method": "DELETE",
"url": "Patient/1234567890"
}
}
]
}
The following samples show how to execute a bundle.
curl
To execute a bundle, make a POST
request and specify the following
information:
- The name and location of the parent dataset and FHIR store
- The location of the bundle file on your local machine
- An access token
The following sample shows a POST
request using curl:
curl -X POST \ -H "Content-Type: application/fhir+json; charset=utf-8" \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ --data @BUNDLE_FILE.json \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir"
Regardless of the outcome of the individual operations, after executing a batch
bundle, the server returns a JSON-encoded representation of a Bundle
resource
of type batch-response
. The Bundle
resource contains one entry for each
entry in the request with the outcome of processing the entry, which could be a
mix of success and error results.
If a transaction bundle is successful, the server returns a JSON-encoded
representation of a Bundle
resource of type transaction-response
containing
one entry for each entry in the request with the successful outcome of the
operation.
If an error occurs while executing a transaction bundle, the response body does
not contain a bundle. Instead, it contains a JSON-encoded OperationOutcome
resource describing the reason for the error. Successful operations that were
rolled back are not reported in the response.
The following sample bundle is the output from successfully executing the above example. The first entry indicates the success of the operation to create a Patient and includes the ID of the new resource. The second entry indicates the success of the delete operation.
{ "entry": [ { "response": { "location": projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/RESOURCE/RESOURCE_ID, "status": "201 Created" } }, { "response": { "status": "200 OK" } } ], "resourceType": "Bundle", "type": "transaction-response" }
PowerShell
To execute a bundle, make a POST
request and specify the following
information:
- The name and location of the parent dataset and FHIR store
- The location of the bundle file on your local machine
- An access token
The following sample shows a POST
request using Windows PowerShell:
$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-RestMethod ` -Method Post ` -Headers $headers ` -ContentType: "application/fhir+json" ` -InFile BUNDLE_FILE.json ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir" | ConvertTo-Json
Regardless of the outcome of the individual operations, after executing a batch
bundle, the server returns a JSON-encoded representation of a Bundle
resource
of type batch-response
. The Bundle
resource contains one entry for each
entry in the request with the outcome of processing the entry, which could be a
mix of success and error results.
If a transaction bundle is successful, the server returns a JSON-encoded
representation of a Bundle
resource of type transaction-response
containing
one entry for each entry in the request with the successful outcome of the
operation.
If an error occurs while executing a transaction bundle, the response body does
not contain a bundle. Instead, it contains a JSON-encoded OperationOutcome
resource describing the reason for the error. Successful operations that were
rolled back are not reported in the response.
The following sample bundle is the output from successfully executing the above example. The first entry indicates the success of the operation to create a Patient and includes the ID of the new resource. The second entry indicates the success of the delete operation.
{ "entry": [ { "response": { "etag": "ETAG", "lastModified": "2020-08-03T04:12:47.312669+00:00", "location": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/RESOURCE/RESOURCE_ID", "status": "201 Created" } }, { "response": { "etag": "ETAG", "lastModified": "2020-08-03T04:12:47.312669+00:00", "status": "200 OK" } } ], "resourceType": "Bundle", "type": "transaction-response" }
Go
Java
Node.js
A sample bundle file is available in the code sample's GitHub repository.
Python
A sample bundle file is available in the code sample's GitHub repository.
Make a PATCH
request
You can use FHIR bundles to make JSON PATCH
requests on FHIR resources.
See Executing a PATCH
request in a FHIR bundle
for more information.
Resolving references to resources created in a bundle
Resources in a transaction bundle can contain references to resources that don't
exist in the target system but are created during bundle execution. The
Cloud Healthcare API resolves the association between the resources using
the entry.fullUrl
field. References that match the entry.fullUrl
value of
another resource in the bundle are rewritten to the ID of the corresponding
resource in the store. This succeeds regardless of the ordering of the
operations in the bundle.
The Cloud Healthcare API accepts the fullUrl
in the following formats:
urn:uuid:UUID
urn:oid:OID
- any URL
- a resource name in the format
RESOURCE_TYPE/RESOURCE_ID
, such asPatient/123
. Using this format is not recommended because thefullUrl
is a placeholder local to the bundle. This can create confusion if a resource in the store has the same name but the resource in the bundle resolves to a different name as a result of a create operation.
The following sample bundle creates a Patient resource and an Observation resource that refers to the Patient resource.
{
"resourceType": "Bundle",
"type": "transaction",
"entry":[
{
"request": {
"method":"POST",
"url":"Patient"
},
"fullUrl": "urn:uuid:05efabf0-4be2-4561-91ce-51548425acb9",
"resource": {
"resourceType":"Patient",
"gender":"male"
}
},
{
"request": {
"method":"POST",
"url":"Observation"
},
"resource": {
"resourceType":"Observation",
"subject": {
"reference": "urn:uuid:05efabf0-4be2-4561-91ce-51548425acb9"
},
"status":"preliminary",
"code": {
"text":"heart rate"
}
}
}
]
}
The following samples show how to execute a bundle.
curl
A sample bundle file is available in the code sample's GitHub repository.
To execute a bundle, make a POST request and specify the following information:
- The name and location of the parent dataset and FHIR store
- The location of the Bundle file in Cloud Storage
- An access token
The following sample shows a POST
request using curl:
curl -X POST \ -H "Content-Type: application/fhir+json; charset=utf-8" \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ --data @BUNDLE_FILE.json \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir"
The following sample bundle is the output from successfully executing the above example. The first entry indicates the success of the operation to create a Patient and includes the ID of the new resource. The second entry indicates the success of the operation to create the Observation and includes the ID of the new resource.
{ "entry": [ { "response": { "etag": "ETAG1", "lastModified": "2020-08-04T16:14:14.273976+00:00", "location": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/datasets/REGION/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_ID/_history/HISTORY_ID", "status": "201 Created" } }, { "response": { "etag": "ETAG", "lastModified": "2020-08-04T16:14:14.273976+00:00", "location": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/datasets/REGION/fhirStores/FHIR_STORE_ID/fhir/Observation/OBSERVATION_ID/_history/HISTORY_ID", "status": "201 Created" } } ], "resourceType": "Bundle", "type": "transaction-response" }
PowerShell
A sample bundle file is available in the code sample's GitHub repository.
To execute a bundle, make a POST request and specify the following information:
- The name and location of the parent dataset and FHIR store
- The location of the Bundle file in Cloud Storage
- An access token
The following sample shows a POST
request using Windows PowerShell:
$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-RestMethod ` -Method Post ` -Headers $headers ` -ContentType: "application/fhir+json" ` -InFile BUNDLE_FILE.json ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir" | ConvertTo-Json
The following sample bundle is the output from successfully executing the above example. The first entry indicates the success of the operation to create a Patient and includes the ID of the new resource. The second entry indicates the success of the operation to create the Observation and includes the ID of the new resource.
{ "entry": [ { "response": { "etag": "ETAG1", "lastModified": "2020-08-04T16:14:14.273976+00:00", "location": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/datasets/REGION/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_ID/_history/HISTORY_ID", "status": "201 Created" } }, { "response": { "etag": "ETAG", "lastModified": "2020-08-04T16:14:14.273976+00:00", "location": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/datasets/REGION/fhirStores/FHIR_STORE_ID/fhir/Observation/OBSERVATION_ID/_history/HISTORY_ID", "status": "201 Created" } } ], "resourceType": "Bundle", "type": "transaction-response" }