Resource Versions and Versioned References
By default, the FHIR server will store a complete change history for all resources on the server. Smile CDR assigns a numeric version ID as a part of the resource metadata in Resource.meta.versionId
, with the first version being assigned version id "1".
Each time a FHIR Update is performed, the version is incremented by 1 and the previous version is preserved. Operations such as the vRead can be used to examine past versions.
It is possible to disable resource history in Smile CDR. This can be done using the following settings:
When resource history is disabled, when a resource is updated the previous version of the resource will be automatically expunged.
Note that this does not make the server completely non-versioned. Resources will still have a version number which increases every time a resource is modified, operations such as vread and history will still be supported, and features such as ETags and ETag-aware updates will still work. Disabling this setting simply means that when a resource is updated, the previous version of the resource will be expunged. This could be done in order to conserve space, or in cases where there is no business value to storing previous versions of resources.
By default, anytime that a resource is modified, a new version of the is created and the previous version is left in place. This makes it easy to see the changes in a resource's contents over time. However, there may be occasions where you want to change the contents of an existing version in place (e.g. to correct an error that should not appear in the change history for some reason).
Rewriting resource history is unavailable by default in Smile CDR and must be enabled using the History Rewrite setting on the FHIR Storage (RDBMS) module.
To initiate a rewrite, the request must include the header X-Rewrite-History
with a value of true
. The body of the request must include the resource with the same ID and version as defined in the PUT request. The following example shows a request for a history rewrite.
PUT [serverBase]/Patient/123/_history/3
Content-Type: application/fhir+json
X-Rewrite-History: true
{
..
id: "123",
meta: {
versionId: "3",
..
}
..
}
In most cases, references between resources are versionless.
For example, suppose you have a Patient resource Patient/123
, and an Observation resource Observation/456
with a Subject reference to the Patient. There may be many versions of the Patient resource on the server, but the Observation will typically not indicate a specific version.
{
"resourceType" : "Observation",
"id": "456",
"subject": {
"reference": "Patient/123"
}
}
By default, Smile CDR will remove any version information in references when it captures data or serializes it out to a client. This is the default behavior since unversioned references are more common in FHIR than versiones ones.
There are valid reasons to want to preserve versions in references however. For example, if you wish to implement a point-in-time architecture where it is always easy to determine which version of the target resource was current when the source resource was created. In this case, the Observation resource would look like this:
{
"resourceType" : "Observation",
"id": "456",
"subject": {
"reference": "Patient/123/_history/8"
}
}
In order to enable this type of reference, several configuration settings are available in Smile CDR.
A pair of settings controls whether Smile CDR will preserve versioned references:
Observation.subject
CarePlan.activity.detail.goal
When using Smile CDR in Repository Mode by combining a FHIR Storage module with a FHIR Endpoint module, these settings are found on the FHIR Storage module and will apply to any sources of data. This includes HTTP/REST FHIR Endpoints, but also includes ETL modules and other sources.
When using Smile CDR with Hybrid Providers Endpoint or the FHIR Gateway Endpoint, these settings are found on the FHIR Endpoint module.
When using Smile CDR in Repository Mode, it is possible to configure Smile CDR to automatically add a version to specific references. For example, suppose you want any ExplanationOfBenefit resources that are saved in the system to point to the current version of the referenced Patient resource at the time that the ExplanationOfBenefit was created.
The Automatically Version References at Paths setting can be configured with one or more resource paths. When a resource is stored, any references found at the specified paths will have the current version of the target appended, if a version is not already present.
Note that the path here is not a FHIRPath expression and can only include element names after the dots. For example:
Observation.subject
CarePlan.activity.detail.goal
The following example shows Automatically Version Referenced at Paths setting in action. In this example, we have a system that stores Patient resources and Claim resources. The Claim resource has a reference to the patient. We will use a FHIR transaction to perform an "upsert" on the Patient, along with a "create" for a new Claim resource.
To start we will configure the Automatically Version References at Paths setting with the following value, reflecting the path containg the reference we want to automatically version.
Claim.patient
Next, we will issue the following transaction (note that many required and useful data elements have been removed from these resources to keep the example simple):
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [ {
"fullUrl": "urn:uuid:bff26b84-d486-4671-9f25-d0d666fdc442",
"resource": {
"resourceType": "Patient",
"identifier": [ {
"system": "http://example.com/mrns",
"value": "12345"
} ],
"name": [ {
"family": "Smith",
"given": [ "John" ]
} ]
},
"request": {
"method": "PUT",
"url": "Patient?identifier=http://example.com/mrns|12345"
}
}, {
"resource": {
"resourceType": "Claim",
"identifier": [ {
"system": "http://example.com/claims",
"value": "98765"
} ],
"patient": {
"reference": "urn:uuid:bff26b84-d486-4671-9f25-d0d666fdc442"
}
},
"request": {
"method": "POST",
"url": "Claim"
}
} ]
}
With the example above, the placeholder (UUID) "patient"
reference in the Claim resource will be replaced with a versioned reference showing the version ID of the Patient after the update.
The auto-version-references-at-path
extension can be added to the Resource.meta
element of the resource instances to enable automatic reference versioning at specified paths:
"meta": {
"extension": [
{
"url": "http://hapifhir.io/fhir/StructureDefinition/auto-version-references-at-path",
"valueString": "focus"
},
{
"url": "http://hapifhir.io/fhir/StructureDefinition/auto-version-references-at-path",
"valueString": "sender"
}
]
}
The following example shows the auto-version-references-at-path
extension in action. In this example, we have a system that updates Patient resources and creates MessageHeader resources. The MessageHeader resource has references to Patient and Location resources. We will use a FHIR transaction to perform an "upsert" on the Patient, along with a "create" for a new MessageHeader resource. The Location resource is not provided in the transaction.
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"fullUrl": "http://localhost:8000/Patient/2254",
"resource": {
"resourceType": "Patient",
"identifier": [
{
"system": "http://example.com/mrns",
"value": "123456"
}
],
"name": [
{
"family": "Doe",
"given": [
"Jane"
]
}
]
},
"request": {
"method": "PUT",
"url": "Patient?identifier=http://example.com/mrns|123456"
}
},
{
"resource": {
"resourceType": "MessageHeader",
"meta": {
"extension": [
{
"url": "http://hapifhir.io/fhir/StructureDefinition/auto-version-references-at-path",
"valueString": "focus"
}
]
},
"focus": [
{
"reference": "Patient/2254"
},
{
"reference": "Location/2253"
}
]
},
"request": {
"method": "POST",
"url": "MessageHeader"
}
}
]
}
As shown below, references with a focus
path in the MessageHeader resource will be replaced with versioned references showing the version ID of the Patient after the update and the latest version of the existing Location resource.
"focus": [
{
"reference": "Patient/2254/_history/3"
},
{
"reference": "Location/2253/_history/2"
}
]