6.15.1Updating Data

 

This section contains information about methods for updating data in the CDR.

6.15.2Patching Data

 
Using the patch operation requires permissions to update the resource being patched (for example: FHIR_WRITE_ALL_OF_TYPE)

Often it is desirable to make a small change to a resource without needing to re-upload the entire content. For example, a resource status field might be changed by an app with no other changes needed.

This type of scenario is a good candidate for the FHIR patch operation. Smile CDR supports three syntaxes for patching:

  • FHIR Patch: This is the most expressive syntax for patching and is recommended for use unless you have a specific reason to need one of the other options. It uses a format described in the FHIR specification as FHIR Patch. Note that support for FHIR Patch was added in Smile CDR 2020.08.R01.
  • JSON Patch: This syntax expresses a changeset in JSON using RFC 6902.
  • XML Patch: This syntax expresses a changeset in XML using RFC 5261.

6.15.2.1Patch Using FHIR Patch

The FHIR Patch format is very powerful and can be used to specify very precise rules for inserting, modifying, and removing data from FHIR resources. See FHIR Patch for details about the format.

The $diff operation can be used to generate patches, which can be helpful when trying to design a patch for a specific scenario.

The following example shows a FHIR Patch being used to update a Patient status:

PATCH Patient/123
Content-Type: application/fhir+json

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueCode": "replace"
    }, {
      "name": "path",
      "valueString": "Patient.birthDate"
    }, {
      "name": "value",
      "valueDate": "1930-01-01"
    } ]
  } ]
}

6.15.2.2Patch Using FHIR Patch (Transaction)

A FHIR Patch may also be submitted as a part of a FHIR transaction.

{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [ {
    "fullUrl": "Patient/123",
    "resource": {
      "resourceType": "Parameters",
      "parameter": [ {
        "name": "operation",
        "part": [ {
          "name": "type",
          "valueCode": "replace"
        }, {
          "name": "path",
          "valueString": "Patient.birthDate"
        }, {
          "name": "value",
          "valueDate": "1930-01-01"
        } ]
      } ]
    },
    "request": {
      "method": "PATCH",
      "url": "Patient/123"
    }
  } ]
}

6.15.2.3Patch Using JSONPatch

The following example shows a JSONPatch being used to update an Observation status:

PATCH Observation/123
Content-Type: application/json-patch+json

[
 { 
   "op": "replace", 
   "path": "/status", 
   "value": "in-progress" 
 }
]

Please note that if you are using "op": "add", you need to suffix the path with /- (e.g. "path": "/identifier/-").

6.15.2.4Patch Using JSONPatch (Transaction)

A JSONPatch may also be submitted as a part of a FHIR transaction using a Binary resource as the payload in order to hold the contents.

{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [
    {
      "fullUrl": "Patient/1",
      "resource": {
        "resourceType": "Binary",
        "contentType": "application/json-patch+json",
        "data": "WyB7ICJvcCI6InJlcGxhY2UiLCAicGF0aCI6Ii9hY3RpdmUiLCAidmFsdWUiOmZhbHNlIH0gXQ=="
      },
      "request": {
        "method": "PATCH",
        "url": "Patient/1"
      }
    }
  ]
}

6.15.3Tag Retention

 

According to the FHIR rules on updating resources, by default when a resource is updated, any tags and security labels will be carried forward even if they are not explicitly listed in the new version.

For example, suppose a resource is created by a client, and in that resource a tag "foo" is listed in Resource.meta.tag. Then, an update is performed by a client but this update does not contain a value in Resource.meta.

According to the FHIR rules, in this case the tag will be copied to the new version of the resource even though it was not explicitly requested.

In many cases this is desired behavior, since this is consistent with how tags are expected to be used.

If a client wishes to override this behavior, they may do so using the X-Meta-Snapshot-Mode header. This header indicates that Tags and/or Security Labels and/or Profile Declarations should be treated as snapshots, meaning that any values not already present should be removed.

The value is a comma-separated list containing the metadata components that should be treated in snapshot mode:

  • TAG - Resource tags
  • PROFILE - Resource profile declarations
  • SECURITY_LABEL - Security labels

An example is shown below:

X-Meta-Snapshot-Mode: TAG, PROFILE, SECURITY_LABEL

If this header is not present, PROFILE will be treated as being in snapshot mode but TAG and SECURITY_LABEL will not.

6.15.4Concurrent Write Errors

 

If a server is serving multiple concurrent requests against the same resource, an HTTP 409 Version Conflict may be returned to the client. For example, if two client requests attempt to update the same resource at the exact same time, this error will be returned for one of the requests. This error is not a bug in the server itself, but instead is a defense against client updates accidentally being lost because of concurrency issues. When this occurs, it is important to consider what the root cause might be, since concurrent writes against the same resource are often indicative of a deeper application design issue.

The following header can be added to individual HTTP requests to instruct the server to avoid version conflict errors:

X-Retry-On-Version-Conflict: retry; max-retries=10