FHIR extensions
Read and write the fields the base specification does not define, including complex extensions that nest further extensions inside.
You can read and write extensions - the fields the base specification does not define. Real-world data always carries some: a patient's birth place, their preferred pharmacy, attributes required by a national Implementation Guide. FHIR stores all of it in extension, a list that any resource or element can contain, where each entry is identified by a URL and holds one typed value.
What an extension looks like
An extension is plain data, e.g. a Patient with a birth place looks like this on the wire:
{
"resourceType": "Patient",
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/patient-birthPlace",
"valueAddress": {"city": "Amsterdam", "country": "NL"}
}
]
}
Read extensions
Because the order of the extension list is never guaranteed, read extensions by their URL with a path matcher rather than by index:
# -*- coding: utf-8 -*-
# Zato
from zato.server.service import Service
birth_place_url = 'http://hl7.org/fhir/StructureDefinition/patient-birthPlace'
class ReadBirthPlace(Service):
name = 'demo.fhir.read-birth-place'
def handle(self) -> 'None':
client = self.fhir['FHIR.Sample']
patient_id = '511a6231-361e-4b8e-8f9c-b183b7813f4d'
patient = client.resources('Patient').search(_id=patient_id).get()
# Select the extension by its URL and read the city from its value
path = ['extension', {'url': birth_place_url}, 'valueAddress', 'city']
city = patient.get_by_path(path)
self.logger.info('Born in %s', city)
Nested extensions
Implementation Guides often define complex extensions whose value is a further list of sub-extensions. The standard patient-nationality extension is one - the outer extension has no value of its own, only inner ones:
{
"url": "http://hl7.org/fhir/StructureDefinition/patient-nationality",
"extension": [
{"url": "code", "valueCodeableConcept": {"text": "Dutch"}},
{"url": "period", "valuePeriod": {"start": "2004-05-01"}}
]
}
Matchers nest the same way the data does:
nationality_url = 'http://hl7.org/fhir/StructureDefinition/patient-nationality'
# From the outer extension by URL, into the inner one by URL, down to the value
path = [
'extension', {'url': nationality_url},
'extension', {'url': 'code'},
'valueCodeableConcept', 'text',
]
nationality = patient.get_by_path(path)
Write extensions
To add an extension, append to the resource's extension list - creating the list first if the resource has none - and save:
# The resource may not have any extensions yet
if 'extension' not in patient:
patient.extension = []
# Add the new one ..
patient.extension.append({
'url': birth_place_url,
'valueAddress': {'city': 'Amsterdam', 'country': 'NL'}
})
# .. and persist the change.
patient.save()
To replace an existing extension, filter it out by its URL first so the list never holds duplicates:
patient.extension = [item for item in patient.extension if item['url'] != birth_place_url]
patient.extension.append({
'url': birth_place_url,
'valueAddress': {'city': 'Rotterdam', 'country': 'NL'}
})
patient.save()
See also
| Page | What it covers |
|---|---|
| Path access | Dotted paths, list indexes and the matchers used above |
| Resources | Create, read, update and delete any FHIR resource |
| FHIR in Europe | The national programs whose guides define extensions |
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