4.10.1FHIRPath Patch

 

The FHIR standard defines a FHIR-native mechanism for expressing changes to a FHIR resource in terms of only the delta you wish to apply. This syntax is called FHIRPath Patch (also often called FHIR Patch).

A FHIRPath Patch document is a Parameters resource with any number of patch operations (add an element, delete an element, etc.). Each operation in the document will be applied in order.

The HAPI FHIR FhirPatchBuilder class can be helpful as a way of generating FHIR Patch documents.

4.10.2Operation: Add

 

The Add operation takes a path to a parent element within a resource (or the name of the resource itself), the name of the element to add, and a value to actually add.

4.10.2.1Example Document

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueString": "add"
    }, {
      "name": "path",
      "valueString": "Patient"
    }, {
      "name": "name",
      "valueString": "identifier"
    }, {
      "name": "value",
      "valueIdentifier": {
        "system": "http://system",
        "value": "value-new"
      }
    } ]
  } ]
}

4.10.2.2Example Java

FhirPatchBuilder builder = new FhirPatchBuilder(myContext);
builder
	.add()
	.path("Patient")
	.name("identifier")
	.value(new Identifier().setSystem("http://system").setValue("value-new"));
IBaseParameters patch = builder.build();

4.10.3Operation: Insert

 

The Insert operation takes a path to a repeatable element, an index to insert at, and a value to actually insert.

4.10.3.1Example Document

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueString": "insert"
    }, {
      "name": "path",
      "valueString": "Patient.identifier"
    }, {
      "name": "index",
      "valueInteger": 1
    }, {
      "name": "value",
      "valueIdentifier": {
        "system": "http://system",
        "value": "value-new"
      }
    } ]
  } ]
}

4.10.3.2Example Java

FhirPatchBuilder builder = new FhirPatchBuilder(myContext);
builder
	.insert()
	.path("Patient.identifier")
	.index(1)
	.value(new Identifier().setSystem("http://system").setValue("value-new"));
IBaseParameters patch = builder.build();

4.10.4Operation: Delete

 

The Delete operation takes a path to an element to delete.

By default, the operation will fail if the path matches multiple elements, but this can be changed with the allowMultipleMatches option as described in Deleting Multiple Elements below.

4.10.4.1Example Document

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueString": "delete"
    }, {
      "name": "path",
      "valueString": "Patient.identifier[1]"
    } ]
  } ]
}

4.10.4.2Example Java

FhirPatchBuilder builder = new FhirPatchBuilder(myContext);
builder
	.delete()
	.path("Patient.identifier[1]");
IBaseParameters patch = builder.build();

4.10.5Deleting Multiple Elements

 

Per the FHIR Patch specification, the specified path must only match one element. This can be controlled by adding an additional parameter to the delete operation called allowMultipleMatches with a boolean value of true.

4.10.5.1Example Document

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueString": "delete"
    }, {
      "name": "path",
      "valueString": "Patient.identifier.where(system='http://system0')"
    }, {
      "name": "allowMultipleMatches",
      "valueBoolean": true
    } ]
  } ]
}

4.10.5.2Example Java

FhirPatchBuilder builder = new FhirPatchBuilder(myContext);
builder
	.delete()
	.path("Patient.identifier.where(system='http://system0')")
	.allowMultipleMatches();
IBaseParameters patch = builder.build();

4.10.6Operation: Replace

 

The Replace operation takes a path to an element to replace, and a value to actually replace it with. The path must resolve to a single element.

4.10.6.1Example Document

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueString": "replace"
    }, {
      "name": "path",
      "valueString": "Patient.identifier[1]"
    }, {
      "name": "value",
      "valueIdentifier": {
        "system": "http://system",
        "value": "value-new"
      }
    } ]
  } ]
}

4.10.6.2Example Java

FhirPatchBuilder builder = new FhirPatchBuilder(myContext);
builder
	.replace()
	.path("Patient.identifier[1]")
	.value(new Identifier().setSystem("http://system").setValue("value-new"));
IBaseParameters patch = builder.build();

4.10.7Operation: Move

 

The move operation takes a path to a repeatable element to move, and a source and destination index.

4.10.7.1Example Document

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueString": "move"
    }, {
      "name": "path",
      "valueString": "Patient.identifier"
    }, {
      "name": "source",
      "valueInteger": 1
    }, {
      "name": "destination",
      "valueInteger": 2
    } ]
  } ]
}

4.10.7.2Example Java

FhirPatchBuilder builder = new FhirPatchBuilder(myContext);
builder
	.move()
	.path("Patient.identifier")
	.source(1)
	.destination(2);
IBaseParameters patch = builder.build();

4.10.8Example: Replace Any Existing LOINC Codes

 

The following example shows a FHIR Patch which operated on an Observation resource. It removes any and all values in Observation.code.coding with a Coding.system value of 'http://loinc.prg', and adds a new LOINC code in their place.

This document should always leave exactly one LOINC code in Observation.code regardless of whether there was previously no such code, one code, or multiple codes.

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueString": "delete"
    }, {
      "name": "path",
      "valueString": "Observation.code.coding.where(system='http://loinc.org')"
    }, {
      "name": "allowMultipleMatches",
      "valueBoolean": true
    } ]
  }, {
    "name": "operation",
    "part": [ {
      "name": "type",
      "valueString": "add"
    }, {
      "name": "path",
      "valueString": "Observation.code"
    }, {
      "name": "name",
      "valueString": "coding"
    }, {
      "name": "value",
      "valueCoding": {
        "system": "http://loinc.org",
        "code": "85354-9",
        "display": "Blood Pressure"
      }
    } ]
  } ]
}

4.10.8.1Java Example

To build this patch document in Java:

FhirPatchBuilder builder = new FhirPatchBuilder(myContext);
// Delete any existing LOINC codes
builder
	.delete()
	.path("Observation.code.coding.where(system='http://loinc.org')")
	.allowMultipleMatches();
// Add a specific LOINC code
builder
	.add()
	.path("Observation.code")
	.name("coding")
	.value(new Coding("http://loinc.org", "85354-9", "Blood Pressure"));
IBaseParameters patch = builder.build();