Lesson 36 of 51 · The FHIR Model

Data Types and Extensions

FHIR Data Types and Extensions

What an element holds

Earlier lessons showed that a FHIR resource is built from elements — named fields such as a Patient’s name or an Observation’s value. Every element has a data type that defines what it can contain. FHIR’s data types come in two families 1.

Primitive types carry a single, atomic value: string, boolean, integer, decimal, uri, code, dateTime, and instant, among others. A code is a constrained string limited to a fixed set of allowed values; dateTime permits varying precision (a year alone, or a full timestamp), while instant requires a precise moment down to the second with a timezone. Each primitive has rules for its allowed format, which lets software validate a value without understanding its meaning.

Complex types are built from other elements — they are small, reusable structures rather than single values. Because the same shapes recur across many resource types, FHIR defines them once and reuses them everywhere.

The high-value complex types

A handful of complex types appear constantly 1:

  • HumanName — the parts of a name (family, given, prefix) plus a use (official, nickname) and a text rendering.
  • Addressline, city, state, postalCode, country, with a use and type.
  • Identifier — a business identifier such as a medical record number, qualified by the system that issues it so the same number from two organizations cannot be confused.
  • Period — a start and end time, used wherever something is valid for a span.
  • Quantity — a measured value with a unit, plus a coded system and code for the unit so “mg” is machine-comparable rather than free text.
  • Reference — a pointer from one resource to another, covered in the previous lesson; it too is simply a data type.

The most important pair is Coding and CodeableConcept, which is where the terminologies course connects directly to the resource model.

Coding and CodeableConcept

The terminologies course introduced the code + system + display triplet: a coded value is never just a code, because the same code means different things in different code systems. FHIR encodes that triplet as the Coding type — a single coded value with a system (the URI naming the code system), a code, and a display (the human-readable label) 1:

{
  "system": "http://loinc.org",
  "code": "789-8",
  "display": "Erythrocytes [#/volume] in Blood by Automated count"
}

A CodeableConcept wraps one or more Codings plus an optional free-text description. Multiple Codings let the same concept be expressed in several code systems at once (a local code and a standard code side by side), and the text preserves the original wording even when no code captures it perfectly 1:

{
  "coding": [
    { "system": "http://loinc.org", "code": "789-8", "display": "RBC count" }
  ],
  "text": "Red blood cell count"
}

This is the direct successor to HL7 v2’s CWE (“coded with exceptions”) data type, which paired a code with its coding system and display text and allowed a free-text fallback. FHIR keeps the same idea — codes are meaningful only alongside the system that defines them — but expresses systems as resolvable URIs and lets a CodeableConcept hold several codings together 2.

Extensions: governed extensibility

No fixed specification can anticipate every local data need, so FHIR builds an escape valve into the model itself: every element in every resource may carry extension entries 1. An extension has a url that defines its meaning — and points to its formal definition — and a single value, recorded in a value[x] element whose name encodes its type (valueString, valueCodeableConcept, valueDateTime, and so on):

{
  "extension": [
    {
      "url": "http://example.org/fhir/StructureDefinition/birthPlace",
      "valueString": "Wellington, NZ"
    }
  ]
}

The design intent is controlled, governed extensibility. Anyone can attach extra data without forking the specification, because an extension’s meaning lives at a resolvable URL that anyone can look up — the data stays self-describing and discoverable 1.

A special variant is modifierExtension. An ordinary extension adds information that a system may safely ignore if it does not recognize it. A modifierExtension, by contrast, changes how the containing element is understood — for example, marking a record as entered in error — and so it must not be ignored. A system that encounters a modifierExtension it does not understand should refuse to process the element rather than silently misinterpret it 1.

This is a more disciplined version of a familiar idea. HL7 v2 met the same need with Z-segments: locally agreed custom segments that worked between two trading partners but were undocumented in the standard and opaque to anyone else. FHIR extensions serve the identical purpose — adding local data — but every extension is URL-defined and discoverable rather than privately negotiated, so the meaning travels with the data instead of living only in a partner agreement 2.

References

  1. HL7 FHIR Release 4 (R4), v4.0.1. HL7 International. 2019. verified Cited at: datatypes.html; extensibility.html.
  2. Tim Benson, Grahame Grieve. Principles of Health Interoperability: FHIR, HL7 and SNOMED CT. 4th ed. Springer. 2021. verified