FHIRPath Patch - Smile CDR Documentation

FHIRPath 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.

Operation: 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.

Example 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"\
      }\
    } ]\
  } ]
}

Copy

Example 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();

Copy

Operation: Insert

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

Example 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"\
      }\
    } ]\
  } ]
}

Copy

Example 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();

Copy

Operation: 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.

Example Document

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

Copy

Example Java

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

Copy

Deleting 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.

Example Document

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

Copy

Example Java

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

Copy

Operation: 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.

Example 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"\
      }\
    } ]\
  } ]
}

Copy

Example 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();

Copy

Operation: Move

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

Example Document

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

Copy

Example Java

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

Copy

Example: 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.org', 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"\
      }\
    } ]\
  } ]
}

Copy

Java 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();

Copy

FHIRPath Expressions

FHIRPath Patch

The FHIR Standard

FHIR Introduction FHIR Versions FHIR CRUD Operations FHIR Searching Basics FHIR Search: References and Includes FHIR Search: Custom Search Parameters FHIR Search: Combo Search Parameters FHIR Search: Enforcing Uniqueness FHIR Search: Uplifted Refchains FHIR Transactions and Batches FHIRPath Expressions FHIRPath Patch