Path access to FHIR data

Read deeply nested FHIR values in one call - dotted paths, list indexes and matchers replace chains of brackets and try/except blocks.

You can read any nested FHIR value in one call. Resources are deeply nested - a patient's family name lives under name[0].family and a phone number under telecom, in the list element whose system is phone - and reaching such values with plain indexing means chains of brackets and try/except blocks for anything optional. Path access condenses that into a single call.

Dotted paths

Every resource has a get_by_path method that accepts a dotted string. Numbers in the path index into lists:

# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class ReadNames(Service):
    name = 'demo.fhir.read-names'

    def handle(self) -> 'None':

        client = self.fhir['FHIR.Sample']
        patient = client.get('Patient', '511a6231-361e-4b8e-8f9c-b183b7813f4d')

        # The first given name of the first name entry
        given = patient.get_by_path('name.0.given.0')

        self.logger.info('Given name is %s', given)

Defaults for missing values

If anything along the path does not exist, the call returns the default instead of raising an exception, which removes the need for defensive checks around optional fields:

# There may be no second name entry at all - the call returns None then
maiden = patient.get_by_path('name.1.family')

# Or provide your own default
maiden = patient.get_by_path('name.1.family', '(none)')

Select list elements by their fields

Positional indexes break when the order of list elements is not guaranteed, which in FHIR it rarely is. Pass the path as a list and use a dict where an index would go - the first list element whose fields match the dict is selected:

# The official name, regardless of its position in the name list
family = patient.get_by_path(['name', {'use': 'official'}, 'family'])

# The home phone number, out of all the telecom entries
phone = patient.get_by_path(['telecom', {'system': 'phone', 'use': 'home'}, 'value'])

The matcher and index styles combine freely in one path:

# The first given name within the official name entry
given = patient.get_by_path(['name', {'use': 'official'}, 'given', 0])

Paths into search results

Data fetched from a server supports the same navigation, including raw Bundles, so a value can be extracted from a search response in one step:

bundle = client.resources('Patient').search(name='Chalmers').limit(1).fetch_raw()

# Straight from the Bundle to the value, the next-page link in this case
next_link = bundle.get_by_path(['link', {'relation': 'next'}, 'url'])

See also

PageWhat it covers
ExtensionsPath matchers applied to extension lists and their URLs
Searches and bundlesThe searches that produce the data paths reach into
ResourcesCreate, read, update and delete any FHIR resource

Learn more


Schedule a meaningful demo

Book a demo with an expert who will help you build meaningful systems that match your ambitions

"We evaluated 12 integration platforms and Zato was the only one to score 100%."

Philip Zuñiga, Assistant Professor, University of the Philippines