Lesson 35 of 51 · The FHIR Model

References, Contained Resources, and Bundles

FHIR References and Bundles

FHIR keeps each resource small, typed, and independently addressable. That design only works because resources can point at one another, and because there is a standard way to package several of them together. This lesson covers the three mechanisms that make that possible: references between resources, contained resources nested inside a parent, and Bundles that carry many resources as one unit.

References

A reference is FHIR’s way of linking one resource to another. It uses a dedicated Reference data type rather than copying data, so a resource is never duplicated — it is only pointed at 1. References are directional: an Observation may reference the Patient it describes through its subject element, but the Patient does not point back. The link lives on the resource that needs the connection.

The most common form is a literal reference, which carries a URL in the reference element. That URL can be relative — a resource type and id such as "Patient/pat-1", resolved against the server you are talking to — or an absolute URL that names the resource on a specific server 1.

{
  "resourceType": "Observation",
  "status": "final",
  "subject": {
    "reference": "Patient/pat-1",
    "display": "Jordan Avery"
  }
}

The optional display element holds a human-readable label for the target. It is a convenience for rendering and must never be treated as the source of truth — always resolve the reference itself to get current data 1.

When you know a business identifier for the target but not its URL, you can use a logical reference instead. Rather than reference, you supply an identifier (for example, a medical record number with its system), and the receiving system resolves it to an actual resource 1.

{
  "subject": {
    "identifier": {
      "system": "http://hospital.example.org/mrn",
      "value": "MRN-00471"
    }
  }
}

Contained resources

Sometimes the thing you want to reference has no meaningful existence on its own. A resource can then contain another resource by inlining it in the parent’s contained array. A contained resource has no independent identity outside its parent and cannot be addressed or retrieved separately 1.

A contained resource is referenced locally using a fragment: a # followed by the inner resource’s local id, such as "#vitals-1" 1.

{
  "resourceType": "Observation",
  "contained": [
    { "resourceType": "Patient", "id": "vitals-1", "name": [{ "text": "Anonymous donor" }] }
  ],
  "status": "final",
  "subject": { "reference": "#vitals-1" }
}

The decision is about identity. Reference when the target is a real, reusable entity that other resources may also point to and that should be maintained on its own. Contain only when the inner resource is so tightly bound to its parent that it has no standalone meaning — it exists solely to give the parent something to point at 1.

Bundles

A Bundle is itself a resource. Its job is to package other resources together, which it does through an entry array where each entry wraps one resource 1. The Bundle.type element declares what kind of collection it is, and that type governs how a server interprets the contents 1:

  • searchset — the results of a search.
  • transaction — a set of changes applied all-or-nothing.
  • batch — a set of independent changes where partial success is allowed.
  • document — a clinical document with a fixed structure.
  • collection — a plain grouping of resources with no special processing.
  • history — the change history of one or more resources.

The contrast between transaction and batch is the important one. In a transaction, every entry succeeds or every entry fails together, so the server treats the whole Bundle as one atomic operation. In a batch, each entry is processed on its own; some may succeed while others fail, and the response reports the outcome per entry 1.

{
  "resourceType": "Bundle",
  "type": "collection",
  "entry": [
    { "resource": { "resourceType": "Patient", "id": "pat-1" } },
    { "resource": { "resourceType": "Observation", "id": "obs-1",
        "status": "final", "subject": { "reference": "Patient/pat-1" } } }
  ]
}

Because a Bundle is a resource 1, it can be stored, exchanged, and referenced like any other — making it the standard envelope for moving collections of FHIR data between systems.

References

  1. HL7 FHIR Release 4 (R4), v4.0.1. HL7 International. 2019. verified Cited at: references.html; bundle.html; resource.html.