GraphDefinition — Describing a resource graph
How to pull "everything connected to a patient" in a single request? GraphDefinition
formally describes the expected resource graph and feeds the $graph
operation.
Purpose
GraphDefinition is the metadata describing a directed graph of FHIR resources linked by References. It serves two main purposes:
- Feeds the
$graphoperation — invoked on a root resource, it returns a searchset Bundle including every reachable resource according to the definition. - Documents in an Implementation Guide what a Bundle (document, message, transaction) must contain for a given use case.
Key fields
| Field | Type | Cardinality | Role |
|---|---|---|---|
url | uri | 0..1 | Canonical URL. |
name | string | 1..1 | Machine name. |
status | code | 1..1 | Publication status. |
start | code | 1..1 | Root resource type of the graph. |
node | BackboneElement[] | 0..* | Graph nodes (types + profiles). |
node.nodeId | id | 1..1 | Local node ID. |
node.type | code | 1..1 | FHIR type of the node. |
node.profile | canonical | 0..1 | Profile on the type. |
link | BackboneElement[] | 0..* | Directed edges. |
link.sourceId | id | 1..1 | Source node. |
link.targetId | id | 1..1 | Target node. |
link.path | string | 0..1 | FHIRPath or reference type. |
link.min / link.max | integer / string | 0..1 each | Link cardinality. |
JSON example
Graph: Patient → Encounter → CareTeam → Practitioner. Usable with
GET /Patient/123/$graph?graph=http://hl7.org/fhir/GraphDefinition/example:
{
"resourceType": "GraphDefinition",
"id": "example",
"url": "http://hl7.org/fhir/GraphDefinition/example",
"version": "5.0.0",
"name": "PatientCareTeamGraph",
"status": "active",
"experimental": false,
"date": "2026-05-14",
"publisher": "HL7 (FHIR Project)",
"description": "Graph Patient + Encounter + CareTeam + Practitioner.",
"start": "Patient",
"node": [
{
"nodeId": "encounter",
"type": "Encounter",
"profile": "http://hl7.org/fhir/StructureDefinition/Encounter"
},
{
"nodeId": "careteam",
"type": "CareTeam",
"profile": "http://hl7.org/fhir/StructureDefinition/CareTeam"
},
{
"nodeId": "practitioner",
"type": "Practitioner",
"profile": "http://hl7.org/fhir/StructureDefinition/Practitioner"
}
],
"link": [
{
"description": "Patient → Encounter",
"min": 0,
"max": "*",
"sourceId": "Patient",
"targetId": "encounter",
"path": "Encounter.subject.where(reference.startsWith('Patient/'))"
},
{
"description": "Encounter → CareTeam",
"sourceId": "encounter",
"targetId": "careteam",
"path": "CareTeam.encounter"
},
{
"description": "CareTeam → Practitioner",
"sourceId": "careteam",
"targetId": "practitioner",
"path": "CareTeam.participant.member"
}
]
} Common pitfalls
- Unbounded cyclic graphs — a graph Patient → RelatedPerson → Patient without
maxcan recurse infinitely. Always bound. - Non-indexable FHIRPath — a
link.pathtoo complex (heavy filters) cannot be executed by the server. - Target profile not loaded — if
node.profilepoints to an unknown StructureDefinition, expansion fails. - Confusing
$graphand$everything—$everythingis defined on Patient and CareTeam only and returns the full record,$graphis parameterised by an arbitrary GraphDefinition.
Related resources
- StructureDefinition — profiles on the nodes.
- OperationDefinition — describes the
$graphoperation consuming a GraphDefinition. - MessageDefinition — may reference a graph via
graph. - Bundle — container returned by
$graph.