Extensibility

Extensions

The FHIR model is designed to meet core requirements for everyone from small independent veterinary clinics to giant healthcare systems. By only including only the details that are relevant for most use cases, the FHIR model is simpler than it would be if it tried to accommodate every use case.

In order to support the requirements that make your use case unique, FHIR provides the ability to extend every FHIR resource to store additional data.

⚠️
Take your time to understand the best place to fit your data into the FHIR model.

Storing your data natively in the FHIR model makes it possible to share that data with other FHIR services easily. Extensions should be used only when there is no other way to store your data in the FHIR model. In our experience, you can generally fit 80-90% of their data into the FHIR store natively.

Anatomy of an Extension

The FHIR specification includes example Extensions in the documentation for each resource. For example, Patient resource extension examples are available here (opens in a new tab). One of the simplest extensions listed there is the 'mothersMaidenName' extension (opens in a new tab) which adds a string value to the Patient resource to hold the Patient's mother's maiden name.

If the Patient's mother's maiden name were 'Smith', the extension would be represented on a FHIR Patient resource as:

{
  "resourceType": "Patient",
  "extension": [
    {
      "url": "http://hl7.org/fhir/StructureDefinition/patient-mothersMaidenName",
      "valueString": "Smith"
    }
  ]
}

If you need to store a piece of data that doesn't fit natively in the FHIR specification take a look at the FHIR specification extension examples before doing the work of creating your own extension. You may find that the extension you need already exists.

Nested Extensions

Extensions can have extensions of their own. This allows for storing a number of related values in a single top-level extension to relate them.

Because the top-level extension url property points to the StructureDefinition which defines how the nested extensions should be used, nested extensions may use relative URLs for their url property. There is no need to define a new StructureDefinition for each nested extension.

Creating an Extension

Making your own extension is a two step process:

  1. Choose a canonical URL for your extension.
  2. Add the extension to a FHIR resource using the extension property.

Extension Canonical URL

The canonical URL is a globally unique absolute URL that you control. For example, it might look like: https://extensions.yourdomain.com/really-cool-extension.

Ideally, you should author and publish a StructureDefinition (opens in a new tab) resource that defines the extension as encouraged by the FHIR specification. The StructureDefinition resource describes the purpose of the extension, and the structure of the data in the extension so that anyone who comes across the extension can visit the canonical URL to understand what the extension is for and how to use it.

In reality, it's a good deal of effort to create, publish, and maintain these StructureDefinition resources, especially during early development phases where they may be in flux. So, it's not uncommon for developers building on FHIR to maintain simpler internal documentation for extensions that they don't intend to share with the world. As long as you're careful to choose a canonical URL that is on a domain that you control, you can always publish a proper StructureDefinition there if it ever becomes necessary.

Add the Extension to a FHIR Resource

Imagine you have a patient application which Patient Users log into to schedule appointments and check lab results. In this app, you might have some nice UI features like a dark mode / light mode toggle, and a notifications toggle. You want to store the Patient's selections for these features so that you can use them to customize the Patient's experience when they log in.

First, you choose the URLs for your extension. You might choose: https://extensions.yourdomain.com/patient-app-preferences for the top-level extension, and dark-mode and notifications-enabled for the nested extensions.

Then, you can add the extension to a Patient's resource when you know their preferences. To make it easier for you to try it out, the example creates a new Patient with the extension, but you can add the extension to an existing Patient resource as well using Update.

Create a FHIR Patient with the https://extensions.yourdomain.com/patient-app-preferences extension using the SDK:

import { Patient } from 'fhir/r4b'; // npm install @types/fhir
import zapehr from '@zapehr/sdk'
 
zapehr.init({
  ZAPEHR_ACCESS_TOKEN: "<your_access_token>",
});
 
const createdResource: Patient = await zapehr.fhir.create<Patient>({
  resourceType: 'Patient',
  active: true,
  name: [
    {
      given: ['Jon'],
      family: 'Snow',
    },
  ],
  address: [
    {
      use: 'home',
      type: 'physical',
      text: 'Winterfell',
    },
  ],
  extension: [
    {
      url: 'https://extensions.yourdomain.com/patient-app-preferences',
      extension: [
        {
          url: 'dark-mode',
          valueBoolean: true,
        },
        {
          url: 'notifications-enabled',
          valueBoolean: false,
        },
      ],
    },
  ]
});

Additional Resources