Transactions
Combining multiple operations in a single transaction can be useful when you need to ensure that all operations succeed or fail together. This page explains how to use FHIR transactions in Atticus.
The Bundle Resource
A FHIR Bundle is a container for a collection of resources. When used for transactions, the Bundle contains a list of operations (create, update, delete) that should be processed atomically - meaning either all operations succeed or none of them do.
Properties
- Name
resourceType*- Type
- 'Bundle'
- Description
The FHIR resource type. This must be set to
'Bundle'.
- Name
type*- Type
- code
- Description
For transactions, this will be set to
'transaction'. For transaction responses, it will be set to'transaction-response'.
- Name
entry*- Type
- Entry[]
- Description
An array of entry objects, each containing a request and a resource. \ Each entry in a transaction request Bundle can have the following properties
- Name
fullUrl- Type
- uri
- Description
A temporary UUID that can be used to reference the resource in other entries. The value must literally match the format
urn:uuid:<uuid>. Using a FHIR-legal absolute URL asfullUrlcauses the whole Bundle to fail with a422error.
- Name
resource- Type
- Resource
- Description
The resource to be created, updated. Not required for DELETE operations.
- Name
request- Description
The request object contains the HTTP method and URL for the operation.
- Name
method*- Type
- code
- Description
The HTTP method for the operation. Must be one of
GET,POST,PUT, orDELETE.
- Name
url*- Type
- string
- Description
The relative URL for the resource. For example,
PatientorEncounter/1.
A detailed description of all properties can be found in the FHIR specification.
Making Transaction Requests
This endpoint allows you to submit a transaction Bundle containing multiple operations. The following example shows how to create a Patient and an associated Encounter in a single transaction.
Request
curl -X POST https://reports.tiro.health/fhir/r5 \
-H "Authorization: Basic {{apikey}}" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"fullUrl": "urn:uuid:4f6a30fb-cd3c-4ab6-8757-532101f72065",
"resource": {
"resourceType": "Patient",
"name": [{
"given": ["John"],
"family": "Smith"
}]
},
"request": {
"method": "POST",
"url": "Patient"
}
},
{
"resource": {
"resourceType": "Encounter",
"status": "in-progress",
"subject": {
"reference": "urn:uuid:4f6a30fb-cd3c-4ab6-8757-532101f72065"
}
},
"request": {
"method": "POST",
"url": "Encounter"
}
}
]
}'
Response
{
"resourceType": "Bundle",
"type": "transaction-response",
"entry": [
{
"resource": {
"resourceType": "Patient",
"id": "1",
"name": [{
"given": ["John"],
"family": "Smith"
}]
},
"link": [
{
"relation": "self",
"url": "Patient/1"
}
],
"response": {
"status": "201",
"location": "Patient/1"
}
},
{
"resource": {
"resourceType": "Encounter",
"id": "1",
"status": "in-progress",
"subject": {
"reference": "Patient/1"
}
},
"link": [
{
"relation": "self",
"url": "Encounter/1"
}
],
"response": {
"status": "201",
"location": "Encounter/1"
}
}
]
}
Transaction Processing Rules
- All resources in a transaction must have a
requestelement specifying the HTTP method and URL - For resources being created (POST), you can provide a temporary UUID in the
fullUrlfield to allow other resources in the bundle to reference it - The server processes the transaction atomically - either all operations succeed or none do
- If any operation fails, the entire transaction is rolled back and an OperationOutcome is returned
- References between resources in the transaction can use the temporary UUIDs specified in
fullUrl - Only resources whose endpoints are transaction-enabled can appear in a bundle entry. Supported resources include
Patient,Encounter,Practitioner,Task,Questionnaire,QuestionnaireResponse,BinaryandDocumentReference, among others. An entry targeting an unsupported path (e.g.PractitionerRole,Composition) aborts the whole bundle with a "No matching route found" error. request.ifNoneExistis accepted in the bundle but is not honored by any endpoint - conditional create silently degrades to a plain create (which may then return a409error on duplicate identifiers).
Response entries are returned in execution order - the server
topologically sorts entries by their urn:uuid dependencies - not in request
order. Do not correlate request entry N with response entry N positionally;
match on the returned resource or response.location instead.
Common Use Cases
- Creating a patient and their initial encounter together
- Creating a patient, an encounter and a draft questionnaire response
- Deleting a group of related resources
- Ensuring referential integrity between resources
Response headers in a Bundle
Most endpoints of the FHIR API use HTTP response headers to provide the exact location of a resource.
The transaction response Bundle keeps these headers in the entry: the response object contains the status code and the location header, and the Link headers are mapped to the entry's link array. Each successful entry also contains the full created or updated resource in resource. Response entries have no fullUrl.
{
"resourceType": "Bundle",
"type": "transaction-response",
"entry": [
{
"resource": {
"resourceType": "QuestionnaireResponse",
"id": "123",
"status": "in-progress"
},
"link": [
{
"relation": "self",
"url": "QuestionnaireResponse/123"
}
],
"response": {
"status": "201",
"location": "QuestionnaireResponse/123"
}
}
]
}
For an exact overview of the headers sent back in the response, refer to the documentation of the specific endpoint.
To open a report in the user interface, create a Task and launch it with the Launch URL.
Error Handling
If any operation in the transaction fails, the server will return an OperationOutcome resource describing the error. No changes will be committed to the database in case of failure.
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "exception",
"diagnostics": "Transaction failed: Invalid resource in entry[0]"
}
]
}