R6 Ballot (1st Draft)

This page is part of the FHIR Specification v6.0.0-ballot1: Release 6 Ballot (1st Draft) (see Ballot Notes). The current version is 5.0.0. For a full list of available versions, see the Directory of published versions

1.4.1 Operations for Large Resources (e.g., Groups/Lists)

FHIR Infrastructure icon Work GroupMaturity Level: 0Standards Status: Draft

This page defines three operations that allow for efficient maintenance of very large Group and List resources. These operations make it possible to add and remove items from the list or group, and to retrieve a focused subset of the information in the list and group without having to transmit the entire resource.

Adding and deleting from the resource can also be done using the PATCH interaction. Implementers are welcome to use the patch interaction but these operations provide more certainty and simplicity, since they are tailored directly to the List and Group resources. Similarly, Implementers can retrieve a subset of a List or Group resources using GraphQL, but not all servers support GraphQL, and these operations are simpler than using GraphQL to filter the data (and potentially quicker for the server than using GraphQL).

This instance-level operation merges array entries into an existing ("target") resource, based on values from a supplied ("input") resource, ignoring any values that are already present in the target.

This example adds up to 2 new members to the member array of Group 123, based on whether these entity/period combinations already exist.

POST /Group/123/$add
Content-Type: application/fhir+json
If-Match: W/"4"

{
  "resourceType": "Group",
  "type": "Person",
  "actual": true,
  "member": [{
    "entity": {"reference": "Patient/123"},
    "period": {"start": "2020-07-10"},
  }, {
    "entity": {"reference": "Patient/456"}
  }]
}

This example adds up to 2 entries to the entry array of List 123, based on whether these item/date combinations already exist.

POST /List/123/$add
Content-Type: application/fhir+json
If-Match: W/"4"

{
  "resourceType": "List",
  "status": "current",
  "mode": "working",
  "entry": [{
    "item": {"reference": "Patient/123"},
    "date": "2020-01-05"
  }, {
    "item": {"reference": "Patient/456"}
  }]
}

There is a formal definition for this operation

Instance-level operation, invoked by

  • POST /Group/123/$add to grow Group.member
  • POST /List/123/$add to grow List.entry
  • (Other target resource types may be added in future, if use cases arise.)

Input Parameter:

  • additions: an input resource matching the type of the target resource. The client SHALL populate all required top-level elements in a way that matches the target resource, to ensure the resource is technically valid. The server SHALL ignore all elements except for the relevant array (e.g., Group.member or List.entry).

Behavior:

  • The server SHALL extend the target resource array with any entries from the input resource array that do not match an existing entry. See Matching Algorithm.

Clients MAY supply an If-Match header with an ETag reflecting the current version of the target resource. Servers SHALL NOT proceed if a supplied ETag does not match the current version of the target resource, following the scheme described at https://hl7.org/fhir/http.html#concurrency.

This instance-level operation removes array entries from an existing ("target") resource, based on a supplied ("input") resource, ignoring any values that are already absent in the target.

This example removes elements from the member array of Group 123 if they match the supplied combinations of entity/period.

POST /Group/123/$remove
Content-Type: application/fhir+json
If-Match: W/"4"

{
  "resourceType": "Group",
  "type": "Person",
  "actual": true,
  "member": [{
    "entity": {"reference": "Patient/123"},
    "period": {"start": "2020-07-10"},
  }, {
    "entity": {"reference": "Patient/456"},
  }]
}

This example removes elements from the entry array of List 123 if they match the supplied combinations of item/date.

POST /List/123/$remove
Content-Type: application/fhir+json
If-Match: W/"4"

{
  "resourceType": "List",
  "status": "current",
  "mode": "working",
  "entry": [{
    "item": {"reference": "Patient/123"},
  }, {
    "item": {"reference": "Patient/456"},
    "date": "2020-01-12"
  }]
}

There is a formal definition for this operation

Instance-level operation, invoked by

  • POST /Group/123/$remove to shrink Group.member
  • POST /List/123/$remove to shrink List.entry
  • (Other target resource types may be added in future, if use cases arise.)

Input Parameter:

  • removals: an input resource matching the type of the target resource. The client SHALL populate all required top-level elements in a way that matches the target resource, to ensure the resource is technically valid. The server SHALL ignore all elements except for the relevant array (e.g., Group.member or List.entry).

Behavior:

  • The server SHALL remove any entries in the target resource’s array that match an entry in the input resource’s array. See Matching Algorithm.

Clients MAY supply an If-Match header with an ETag reflecting the current version of the target resource. Servers SHALL NOT proceed if a supplied ETag does not match the current version of the target resource, following the scheme described at https://hl7.org/fhir/http.html#concurrency.

This instance-level operation returns the subset of array entries from an existing ("target") resource that match values from a supplied ("input") resource.

This example filters List 123 to return items referencing Patient 456 (on any day) Patient 789 (in July 2022.

POST /List/123/$filter
Content-Type: application/fhir+json

{
  "resourceType": "List",
  "status": "current",
  "mode": "working",
  "entry": [{
    "item": {"reference": "Patient/456"},
  }, {
    "item": {"reference": "Patient/789"},
    "date": "2022-07"
  }]
}

If this list included two items (with any date) referencing Patient 456, and one item with a date in July 2022 referencing Patient 789, then three subsetted entries would be returned:

{
  "resourceType": "List",
  "id": "123",
  "meta": {
    "tag": [{
      "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationValue",
      "code": "SUBSETTED"
    }]
  },
  "status": "current",
  "mode": "working",
  "title": "Patient waiting list",
  "entry": [{
    "date": "2022-07-01",
    "flag": {"text": "Registered"},
    "item": {"reference": "Patient/456/_history/1"}
  }, {
    "date": "2022-07-02T11:00:00Z",
    "flag": {"text": "Escalated"},
    "item": {"reference": "Patient/456/_history/2"}
  }, {
    "date": "2022-07-02T12:00:00Z",
    "flag": {"text": "Escalated"},
    "item": {"reference": "Patient/789"}
  }]
}

There is a formal definition for this operation

Instance-level operation, invoked by

  • POST /Group/123/$filter to return a filtered subset of Group.member
  • POST /List/123/$filter to return a filtered subset of List.entry
  • (Other target resource types may be added in future, if use cases arise.)

Input Parameter:

  • probes: an input resource matching the type of the target resource. The client SHALL populate all required top-level elements in a way that matches the target resource, to ensure the resource is technically valid. The server SHALL ignore all elements except for the relevant array (e.g., Group.member or List.entry).

Behavior:

  • The server SHALL determine which existing array entries in the target resource "match" each entry in the input resource. See Matching Algorithm.
  • The server SHALL return a resource that includes all matching array entries
  • The returned resource SHALL include a SUBSETTED Coding in .meta.tag

Applies to: $add, $remove, and $filter.

This algorithm determines whether an entry in the target resource array "matches" an entry in the input resource array. An entry is considered to "match" if:

  • each supplied element in the input entry is present in the target entry AND
  • each supplied element has a value in the target entry that is:
    • identical to the value in the input entry OR
    • more specific than the value in the input entry
      • a date is "more specific" if it covers a narrower timespan, e.g. an input value of "2022-07" would match a target value of "2022-07-01"
      • a reference is "more specific" if it points to a historical version, e.g. an input value of "Patient/123" would match a target value of "Patient/123/_history/456"

Entry in input resource:

{
  "item": {"reference": "Patient/123"}
}

Entry in target resource:

{
  "date": "2022-07-01",
  "item": {"reference": "Patient/123/_history/2"}
}

Result: this is a match, because the target entry contains a matching element for the input entry’s elements (item and item.reference). The presence of an additional date element in the target resource does not affect the result.


Now consider the same inputs from Example (1), but swap their roles (input / target) as follows.

Entry in input resource:

{
  "date": "2022-07-01",
  "item": {"reference": "Patient/123/_history/2"}
}

Entry in target resource:

{
  "item": {"reference": "Patient/123"}
}

Result: this is not a match, because the target entry contains no match for the input entry’s date element, and also no match for the input entry’s version-specific item.reference element. This example shows that the comparision operation is not symmetric; inputs match more-specific targets, not less-specific targets.