# 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 is at `name[0].family` and a phone number is 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 {#dotted-paths}

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

```python
# -*- 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 {#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:

```python
# 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 {#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:

```python
# 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:

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

## Paths into search results {#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:

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

# One path leads 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 {#see-also}

- [Extensions](https://zato.io/docs/dev/healthcare/hl7/fhir/extensions/index.html) - Path matchers applied to extension lists and their URLs
- [Searches and bundles](https://zato.io/docs/dev/healthcare/hl7/fhir/bundles/index.html) - The searches that produce the data paths reach into
- [Resources](https://zato.io/docs/dev/healthcare/hl7/fhir/resources/index.html) - Create, read, update and delete any FHIR resource

## Learn more {#learn-more}

- [Healthcare interface engine](https://zato.io/docs/dev/healthcare/) - Clinical messages, FHIR, conversion and operations
- [HL7 v2 parsing](https://zato.io/docs/dev/healthcare/hl7/v2/parsing/) - Messages as typed objects, with field access and validation
- [MLLP channels](https://zato.io/docs/dev/healthcare/hl7v2/mllp/) - Receiving and sending HL7 v2 over MLLP sockets
- [FHIR integrations](https://zato.io/docs/dev/healthcare/hl7/fhir/) - Read and write FHIR resources, with paths, bundles and extensions
- [HL7 v2 to FHIR](https://zato.io/docs/dev/healthcare/hl7/to-fhir/) - Converting v2 messages into FHIR bundles, codes and references included
- [EDIFACT](https://zato.io/docs/dev/healthcare/edifact/) - Parsing interchanges, dialects and the transports they arrive on
- [Transformation](https://zato.io/docs/dev/healthcare/transformation/) - One message in, another standard out, in ordinary Python
- [Audit log](https://zato.io/docs/dev/healthcare/audit-log.html) - Every message with its acknowledgment, searchable by patient identifier
- [AI in clinical interfaces](https://zato.io/docs/dev/healthcare/ai/) - Services calling LLMs and AI agents calling clinical services as tools
