FHIR resources will typically refer to each other, forming a web of related and referenced resources.
Resources refer to each other using the Reference datatype, and can take several forms:
A simple example of a Patient resource with a reference to the Organization which manages the record is shown below:
{
"resourceType": "Patient",
"id": "example",
"name": [ {
"family": "Jones",
"given": [ "David" ]
} ],
"managingOrganization": {
"reference": "Organization/acme"
}
}
The corresponding Organization is shown below:
{
"resourceType": "Organization",
"id": "acme",
"name": "ACME Corporation"
}
Most references will only point in one direction. In other words, Patient contains a reference to its Organization, but Organization does not contain a reference to its patient.
The following example shows a collection of resources with various references. This data will be used for all of the examples on the rest of this page.
Selected search parameters are also shown for each resource, using the form: name (type): path
FHIR searches can be used to find resources which refer to other resources. For example, the following search finds any Observation resources which have patient P1 as a subject:
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1.
Searches may be performed using any search parameter with a parameter type of reference. For example, see the FHIR Patient Resource Default Search Parameters to see what is available out of the box. You can also create Custom Search Parameters.
FHIR also supports a search syntax called chaining, where you can find resources that refer to other resources, but using a property of the other resource that isn't the resource ID. This syntax takes the following form:
[resourceType]?[reference search parameter].[search parameter on reference target]=[value]
For example, suppose you wish to find all Observation resources belonging to a specific patient, but you have only the patient's identifier, not their ID. You can perform this search by searching for Observations using the subject search parameter, but then chaining on the Patient's identifier search parameter. This is shown in the example below:
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1
If you know the target type of the reference, it is possible to include it and improve the specificity of the search. You can do this by appending :[resourceType] before the dot. For example, the following search fetches Observations with a Patient subject named "smith".
http://localhost:8000/Observation
This can be very helpful in terms of improving performance of this query, so you should always include the type of the target if you know it. This is the case because reference search parameters such as Observation?subject= can refer to multiple target types (in this case: Patient, Group, Device, Location, and several more) and the server will have to do more work if it needs to check for all of these possible target types.
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1.
In addition to searching for resources where a reference target has a given parameter value (i.e. chaining), you can also perform searches where a resource referring to the resource being searched for has a given target.
This is an advanced FHIR feature, and can be tricky to understand (and is generally tricky even for FHIR experts to remember the syntax!).
This syntax takes the form:
[resourceType]?_has:[referring resourceType]:[referring parameter]:[parameter]=[value]
An example may help to make this syntax more clear. Suppose you want to search for Patients named Simpson, but only include patients who are members of the group with identifier http://ids|8000
. The "named Simpson" part is easy: you can perform a normal search for Patient?name=Simpson. However, the group part is harder. The following example shows how to do this.
http://localhost:8000/Patient
Note the _has parameter. It includes the following segments:
Results: The search above will return the following resource: Patient/P1.
It is often convenient to be able to search for a collection of resources matching some given criteria, but to also include related resources in the same search result in order to avoid having to perform multiple lookups. This can be achieved using a search feature called includes.
Includes can be used to return any resources which are referred to by the resources returned by the initial search. This syntax takes the following forms:
[resourceType]?[any search parameters]&_include=* [resourceType]?[any search parameters]&_include=[resourceType]:[referring parameter]
The following example shows a search for any body-weight Observations, and includes the subject (Patient) associated with the returned Observations as well:
http://localhost:8000/Observation
Results: The search above will return the following resources: Observation/O1, Observation/O2, Patient/P1, and Patient/P2.
In addition to returning resources that are returned by search results, you can also instruct the _include parameter to return resources referred to by resources that were added to the search results by the _include parameter. This is done using a modifier called :iterate. (Note that in older versions of the FHIR specification, this modifier was called :recurse. Many servers will support both modifiers and treat them identically.)
The following example shows a search for any body-weight Observations, and includes the subject (Patient) associated with the returned Observations, as well as the Organizations referred to by the subject:
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1, Observation/O2, Patient/P1, Patient/P2, and Organization/O1. If the :iterate modifier had not been included on the second _include parameter, the Organization would not have been included in the results.
Resources can also be included based on references flowing in the other direction, meaning resources referring to the search results. This is referred to as reverse includes, or revincludes.
This syntax takes the following forms:
[resourceType]?[any search parameters]&_revinclude=* [resourceType]?[any search parameters]&_revinclude=[referring resourceType]:[referring parameter]
For example, the following search returns any patients with an identifier system of http://ids
, and also returns any Group or Encounter resources which refer to these patients. Note also the token syntax of "[system]|" which means tokens with the given system and any value:
http://localhost:8000/Patient
Results: The search above will return the following resources: Patient/P1, Patient/P2, Group/G1, Encounter/E1, and Encounter/E2.
While references between resources are almost always relative or absolute URLs to other separate resources, FHIR also provides a mechanism called containing where you can embed a resource inside another resource.
This feature is intended for situations where you do not have enough information to create a discrete identity for the resource in question. For example, suppose you have a collection of Observations you wish to model in FHIR, and you have the name and birthdate for the subject but no other information about them. In this case, you have no way of knowing whether two observations belonging to "John Smith" refer to the same person or not. This is an appropriate time to use contained resources.
Contained resources are placed within an array element called "contained" at the root of the resource, and are referred to elsewhere using the syntax { "reference": "#[id]" }
. The following example shows an Observation with a contained Patient.
{ "resourceType": "Observation", "id": "O1", "contained": [ | |
Contained Patient resource within Observation resource | { "resourceType": "Patient", "id": "pat", "name": [ { "family": "Smith", "given": [ "John" ] } ], "birthDate": "1980-07-22" } |
], "subject": { | |
Fragment reference to contained resource | "reference": "#pat" |
}, "status": "final", "code": { "coding": [ { "system": "http://loinc.org", "code": "29463-7", "display": "Body Weight" } ] }, "valueQuantity": { "value": 67.1, "unit": "kg", "system": "http://unitsofmeasure.org", "code": "kg" } } |
Chaining can be used to search values in contained resources. The following URL can be used to fetch the resource above:
http://localhost:8000/Observation
Some resource types define references to other resources which are canonical references. This means that the reference isn't a local or remote address to the resource in question, but instead is an absolute URL representing the canonical URL defined in the target resource. The canonical URL is a URL placed in an element called url
at the root of the resource.
For example, Questionnaire resources define a canonical URL as shown in the example below.
{
"resourceType": "Questionnaire",
"id": "123",
"meta": {
"versionId": "2"
},
"url": "http://acme.org/foo-system/patient-survey",
"version": "13.27Q",
// ....additional fields not shown....
}
Along with the canonical URL in the example url
element shown above, a canonical version is also present in the version
element. Note how these are both separate from the resource instance ID (123) and the resource instance version (2).
The canonical version is a business version as opposed to the technical version stored in the versionId
element. The technical version (versionId) simply refers to the number of times that an individual resource instance has been updated on the server, with the latest version being considered the active one.
The canonical version on the other hand does not necessarily indicate which version is the newest, or which versioh is active. In reality, often times several business versions will be active and present on a server at the same time.
Where technical versions are always a number in HAPI FHIR / Smile CDR (these are alwyas assigned by the server), the business version is simply a string token in any format since it is defined externally to the server.
A QuestionnaireResponse instance contains a reference to the Questionnaire using this canonical reference. For example this could look like the following:
{
"resourceType": "QuestionnaireResponse",
"id": "456",
"questionnaire": "http://acme.org/foo-system/patient-survey",
// ....additional fields not shown....
}
The QuestionnaireResponse could also contain a versioned canonical reference, which appends a pipe (|) and the version into the reference to indicate the specific business version being linked to.
{
"resourceType": "QuestionnaireResponse",
"id": "456",
"questionnaire": "http://acme.org/foo-system/patient-survey|13.27Q",
// ....additional fields not shown....
}
Using the examples above, the following queries could be used to fetch both the QuestionnaireResponse and the corresponding Questionnaire shown in the examples.
Searching for the QuestionnaireResponse and including the Questionnaire it references:
http://localhost:8000/QuestionnaireResponse
Searching for the Questionnaire and reverse including the QuestionnaireResponse which references it:
http://localhost:8000/Questionnaire
In HAPI FHIR / Smile CDR, note the following limitations to how includes/revincludes work for canonical references:
Include Style | Example | Notes |
---|---|---|
Include Reference | _include=QuestionnaireResponse:questionnaire |
If the reference contains a versioned canonical reference, all resources which match the canonical URL will be returned, not just the resource with the matching canonical version. |
Include All | _include=* |
This style can be inefficient for the server to process when using canonical references! If your use case is performance sensitive, it is recommended to use the specific reference parameter as shown above. If the reference contains a versioned canonical reference, all resources which match the canonical URL will be returned, not just the resource with the matching canonical version. |
Reverse Include Reference | _revinclude=QuestionnaireResponse:questionnaire |
If the reference contains a versioned canonical reference, all resources which match the canonical URL will be returned, not just the resource with the matching canonical version. |
Include All | _revinclude=* |
This is not currently supported for canonical references, and will yield no results. |
This example combines chaining and reverse chaining to create a very complicated query that achieves a very interesting result.
Suppose you want to search for Body-Weight observations, but only return observations where the subject is in a collection of patients.
If your collection of patients is small, a simple OR expression on a subject search parameter can do the trick as shown below:
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1, Observation/O2.
However, what if your collection of patients is too large to be maintainable in a URL? Or what if you want to dynamically manage this collection of patients and reuse it across queries? In that case, you could create a Group resource and manage your list of patients there.
Then, you can perform the desired search using the Observation subject search parameter, but chaining on the patient using a reverse chain towards the Group resource. The following example shows this:
http://localhost:8000/Observation
Note the subject parameter. It includes the following segments:
Results: The search above will return the following resources: Observation/O1, and Observation/O2.