Written and maintained by CASRAI Editorial Board
Last updated
FHIRPath is the normative, path-based navigation and extraction expression language developed by Health Level Seven International (HL7) to query, filter, and validate hierarchical clinical data across HL7 FHIR resources and Clinical Quality Language (CQL) artifacts. Unlike XPath (which is bound to XML) or JSONPath (which is bound to JSON syntax), FHIRPath operates on the abstract logical graph model of a FHIR resource—ensuring that validation invariants, search parameter extractions, and clinical decision support rules execute identically regardless of how the data is serialized over the wire.
What Is FHIRPath and How Is It Used in Resource Invariants and CQL?
Defined in the HL7 FHIRPath Normative Specification (Release 2.0), FHIRPath treats every input, intermediate step, and output as an ordered collection of items. There is no null value in FHIRPath; a missing element or unmatched filter simply returns an empty collection ({ }), and Boolean operators follow three-valued logic (true, false, or empty { }).
- Enforcing
StructureDefinitionResource Invariants: Every formal constraint in a FHIR profile (ElementDefinition.constraint.expression) is written in FHIRPath. For example, invariantobs-7on theObservationresource requires that if a top-level value is present, no child component with the exact same code may exist:value.empty() or component.code.where(coding.intersect(%resource.code.coding).exists()).empty(). Similarly, US Core and FHIR Questionnaire SDC profiles use FHIRPath to drive conditional display (enableWhenExpression) and calculated scores (calculatedExpression). - Foundation of Clinical Quality Language (CQL): HL7 CQL—used to author electronic Clinical Quality Measures (eCQMs) and computable clinical guidelines—embeds FHIRPath as its core path-navigation and collection-filtering grammar. Every path traversal in CQL is a valid FHIRPath expression.
- Terminology Validation via
%terminologies: FHIRPath natively connects to a FHIR terminology server through thememberOf(valueSetUrl)function and the%terminologiesenvironment variable (for example,Observation.code.memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult')), invokingValueSet/$validate-codeorCodeSystem/$subsumesunder the hood.
| FHIRPath Function / Operator | Syntax Example | What It Evaluates in a FHIR Server |
|---|---|---|
where(criteria) |
Patient.name.where(use = 'official').family |
Filters a repeating element collection and projects the matching child property |
exists([criteria]) / empty() |
Patient.identifier.exists(system = 'http://hl7.org/fhir/sid/us-ssn') |
Returns true if at least one item in the collection satisfies the condition |
ofType(type) |
Observation.value.ofType(Quantity).value > 140 |
Narrows polymorphic choice elements (value[x]) to a specific data type before comparison |
resolve() |
Observation.subject.where(resolve() is Patient) |
Dereferences a FHIR Reference (e.g., Patient/123) to inspect the target resource’s type or fields |
memberOf(valueSet) |
Condition.code.memberOf('http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.103.12.1001') |
Queries the FHIR terminology server to verify whether a Coding or CodeableConcept belongs to the canonical ValueSet |
implies |
maritalStatus.exists() implies birthDate.exists() |
Logical implication operator heavily used in StructureDefinition invariants (if A is true, B must be true) |
How Do FHIR Search Parameters, Modifiers, and _include Queries Work?
In a FHIR server (such as HAPI FHIR or Firely Server), every SearchParameter resource uses a FHIRPath expression (in SearchParameter.expression) to tell the database indexer which element(s) to extract when a resource is saved. Once indexed, clients query those fields via HL7 FHIR Search:
- Core Search Parameter Types: FHIR defines specialized search parameter data types—including
token(forCoding,CodeableConcept, andIdentifierformatted as[system]|[code]),reference(for links between resources),date(supporting prefixeseq,gt,lt,ge,le),quantity, andstring. - Search Modifiers: Appended with a colon to refine matching behavior—including
:exact(case- and accent-sensitive string match),:contains(substring match),:missing=true|false(presence check), and terminology-aware modifiers:in,:not-in,:above, and:below(which query the FHIR terminology server hierarchy for SNOMED CT or LOINC subsumption). - Chaining (
.) and Reverse Chaining (_has): Chained parameters traverse references in a single query (e.g.,GET /Observation?subject:Patient.name=Smith), whereas_hasfilters a parent resource by child resources that point to it (e.g.,GET /Patient?_has:Observation:patient:code=http://loinc.org|4548-4). - Graph Inclusion (
_includeand_revinclude): To avoid N+1 round-trip queries,_includeinstructs the server to return referenced target resources inside the same searchBundle(e.g.,GET /MedicationRequest?patient=123&_include=MedicationRequest:requester), while_revincludepulls in resources that reference the matched entries (e.g.,_revinclude=Provenance:target).
How Do Topic-Based FHIR Subscriptions and AuditEvent Complete the Architecture?
- Topic-Based FHIR Subscriptions: Rather than polling FHIR search endpoints, topic-based FHIR Subscriptions use
SubscriptionTopicdefinitions—which can evaluate both FHIR search queries and FHIRPath criteria (resourceTrigger.fhirPathCriteria, such as%previous.status != 'final' and %current.status = 'final')—to push real-timerest-hookorwebsocketnotifications to external clinical and research systems whenever a state transition occurs. - FHIR
AuditEventProvenance and Security Logging: Whenever a client executes a FHIR search query, invokes a terminology operation, or receives a subscription payload containing Protected Health Information (PHI), the server records anAuditEventresource (aligned with IHE ATNA and ASTM E2147) capturing the actor (agent), timestamp (recorded), action code (C,R,U,D,E), patient entity, and the exact query parameters executed.
Frequently Asked Questions
What is FHIRPath and how is it used in resource invariants and CQL?
FHIRPath is HL7’s normative path-navigation and expression language that evaluates collections of elements across the logical tree of a FHIR resource. It is used inside StructureDefinition profiles to write validation invariants (ElementDefinition.constraint.expression), inside SearchParameter definitions to specify indexed paths, and as the underlying path and filtering grammar of Clinical Quality Language (CQL).
How do FHIR search parameters, modifiers, and _include queries work?
FHIR servers index resource elements extracted via each SearchParameter‘s FHIRPath expression. Clients query those parameters using typed syntax (token, date, reference, string), refine matches with modifiers (such as :exact, :missing, or terminology-backed :in and :below), and bundle related resources in a single HTTP response using _include (forward references) and _revinclude (reverse references).
How do topic-based FHIR Subscriptions notify external systems of clinical events?
In topic-based FHIR Subscriptions, the server evaluates resource changes against a canonical SubscriptionTopic (using query criteria or FHIRPath state-comparison expressions comparing %previous and %current) and pushes a notification Bundle over a registered Subscription channel (such as rest-hook or websocket) using empty, id-only, or full-resource payload modes.







