Каждое поле внутри FHIR-ресурса называется element — это содержимое «карточки» из fhir-basics. Эта страница — глоссарий устройства одной карточки: какие категории значений бывают, как описывается cardinality, какие DataTypes часто встречаются, какие universal slots есть на каждом ресурсе.
В FHIR-спеке Element — это базовый abstract class от которого наследуется всё (включая BackboneElement, DataType, и каждое поле в каждом ресурсе)1.
1. Три категории элементов
Внутри карточки лежит контент трёх «уровней»:
-
Primitive types — атомарные значения.
string,code,integer,dateTime,uri,boolean,decimal. Не имеют внутренней структуры — одно значение."status": "final" // code — примитив "birthDate": "1980-03-15" // date — примитив "active": true // boolean — примитив -
DataTypes (complex types) — структуры без identity, существуют только внутри ресурса.
Identifier,CodeableConcept,Reference,HumanName,Quantity,Period,Annotation,Address. Не хранятся самостоятельно, не имеют URL."name": { // HumanName — DataType "family": "Иванов", "given": ["Иван", "Сергеевич"] } -
Resources — структуры с identity (
id+ URL), хранятся в FHIR-сервере отдельно.Patient,Observation,Condition,Composition. Связи с другими карточками — через DataTypeReference, который указывает на URL.
Patient (Resource — имеет id, хранится на сервере)
├── name: HumanName (DataType — без id, лежит внутри)
│ ├── family: "Иванов" ← primitive (string)
│ └── given: ["Иван", ...] ← массив primitive
├── birthDate: "1980-03-15" ← primitive (date)
└── managingOrganization: Reference ← DataType ссылка
└── reference: "Organization/clinic-1" ← primitive (string-URL)
DDD-параллель: Resource ≈ Entity (имеет identity), DataType ≈ Value Object (без identity, equal-by-value). См. domain-driven-design.
На реальном примере — US Core Lab Observation

Канонический US Core Lab Result example — Serum Total Bilirubin. Профайл: us-core-observation-lab. Источник Mermaid — attachments/uscore-observation-lab-elements.mmd.
На что смотреть:
- 🟦
Observation— Resource (idserum-total-bilirubin, хранится на сервере по/Observation/{id}). - 🟦 пунктир — другие Resources (
Patient/example,Specimen/serum), на которые ссылается Observation черезReference. - 🟩 DataTypes (без identity, живут внутри):
code,category,interpretation(все три —CodeableConcept);valueQuantity(Quantity— choice typevalue[x]разрешённый в Quantity);subject/specimen(Reference);referenceRange[0](BackboneElement — inline struct). - 🟨 Primitive поля — каждое атомарное значение отдельной нодой:
status: 'final',effectiveDateTime: '2005-07-07'(choice typeeffective[x]разрешённый в primitive date),value: 8.6+unit: 'mg/dL'+system + codeвнутри Quantity, и т.д. - 🟥 Universal slot
metaсprofile[0]— claim of conformance к us-core-observation-lab v7.0.0.
Этот один пример покрывает всю таксономию страницы: три категории, два choice types (effective[x] → primitive, value[x] → DataType), два Reference’а на внешние ресурсы, BackboneElement как третий вид inline-структуры, и universal slot meta.
2. Notation полей — как описывается одно поле в спеке
Когда читаешь FHIR-спеку (hl7.org/fhir/R4/<resource>.html), у каждого поля в таблице показано несколько маркеров:
- Cardinality —
min..max(0..1,1..1,0..*,1..*) - Type — какой DataType / Resource в этом поле (
string,CodeableConcept,Reference(Patient), …) - Flags — компактные маркеры в отдельной колонке:
Σ— element включается в summary view?!— modifier, влияет на интерпретацию ресурса (нельзя игнорировать)I— на поле висят invariants (FHIRPath constraints)S— must-support (в IG);NE— non-empty
- Binding — для code/Coding/CodeableConcept полей:
required/extensible/preferred/example(насколько строго привязан value set) [x]суффикс в имени — поле может быть одного из нескольких типов (choice type)
Ниже разбираем cardinality и choice types подробнее — это самые часто встречающиеся в обсуждениях. Про флаги (особенно ?! modifier) — отдельные секции в fhir-conformance-resources; binding — в fhir-terminology-service.
Cardinality (min..max)
В FHIR-спеке каждое поле сопровождается записью min..max2:
| Запись | Что значит |
|---|---|
0..1 | Optional, не более одного. Может отсутствовать или быть одно значение. |
1..1 | Required, ровно одно. Обязано присутствовать. |
0..* | Optional массив. Может отсутствовать, быть пустым, или содержать любое число элементов. |
1..* | Массив, обязан содержать хотя бы один элемент. |
2..4 | Массив, от 2 до 4 элементов (редко, обычно встречается в специфичных профилях). |
min— минимальное число вхождений (0= optional,1+= required)max— максимальное (1= singular,*= unbounded)
0..* — самый частый кардинальный паттерн для коллекций (Patient.identifier, Observation.component, Bundle.entry). Порядок элементов в массиве стандартом не специфицирован — нельзя полагаться на array[0], надо искать по system / code / discriminator поля. Профилирование через slicing решает эту проблему (см. fhir-profiling).
В FHIR-builder коде кардинальность определяет shape кода: 1..1 поле — всегда обязательный аргумент функции; 0..* — массив с возможно нулевой длиной; 0..1 — optional с if проверкой при сериализации.
Choice types ([x] суффикс)
Когда поле может содержать значение одного из нескольких типов, спека пишет имя[x] с квадратным «x» в суффиксе. В реальном JSON это разворачивается в одно конкретное имя — <имя><Тип> — и только одно значение задаётся одновременно (не оба):
// authorReference вариант:
{ "authorReference": { "reference": "Organization/bloodgpt" }, "time": "...", "text": "..." }
// authorString вариант:
{ "authorString": "Dr. Smith", "time": "...", "text": "..." }Примеры choice types в стандарте:
Annotation.author[x]—authorReference(Practitioner / Device / Organization / Patient) илиauthorString(свободная строка)Observation.value[x]—valueQuantity/valueCodeableConcept/valueString/valueBoolean/ … (≈15 типов)Observation.effective[x]—effectiveDateTime/effectivePeriod/effectiveInstant/effectiveTimingProcedure.performed[x]—performedDateTime/performedPeriod/performedString(для нечётких дат типа «5 лет назад»)MedicationStatement.medication[x]—medicationCodeableConcept(просто код) илиmedicationReference(на отдельныйMedicationресурс)Patient.deceased[x]—deceasedBoolean/deceasedDateTimeExtension.value[x]— universal для extensions (valueString/valueQuantity/ любой data type)
Паттерн «Reference vs String» (богатая ссылка vs простая строка) — частный случай: даёт выбор между референсной структурой (с metadata, versioning, search) и быстрой текстовой строкой. Reference используется когда сущность за полем — самостоятельная (Practitioner с credentials), String — когда хочется short-circuit и сохранять только имя без полной модели.
Failure mode parsing’а — попытаться задать оба варианта (authorReference + authorString в одном объекте). FHIR-валидаторы это ловят как ошибку схемы.
3. Ключевые DataTypes
Здесь — три DataTypes которые нужно понимать чтобы читать любой клинический ресурс: они задействованы в специфичных паттернах работы (matching по system+value, multi-coding, ссылки-vs-identifier-vs-contained). Остальные complex types (Quantity — число с единицей, Period — диапазон дат, HumanName, Address, ContactPoint, Annotation, Timing — расписание, Attachment, Ratio, Range, Money) grok’аются на лету по форме — полный список и поля каждого в hl7.org/fhir/R4/datatypes.html3.
Identifier — бизнес-идентификаторы
Identifier — DataType для бизнес-идентификаторов (MRN — Medical Record Number, SSN — Social Security Number, lab accession number, и т.п.). Структура:
{
"system": "http://hospital.example.org/mrn", // namespace (что за идентификатор)
"value": "P-12345", // значение в этом namespace
"use": "official", // usual | official | temp | secondary | old
"type": { ... }, // optional CodeableConcept
"period": { ... } // когда действителен
}Ключевое: system + value это пара. Один и тот же value (например "12345") может значить разные вещи в разных system. Поэтому идентификаторы матчатся парой, не одним value:
patient.identifier.find(i =>
i.system === "http://hospital.example.org/mrn" && i.value === "P-12345"
)system обычно — URL (http://hospital.example.org/mrn) или OID URN (urn:oid:2.16.840.1.113883.4.1 для US SSN). Каноничные system URLs для регулируемых идентификаторов фиксируются в IG (US Core / RuCore).
CodeableConcept / Coding / code — три уровня кодирования
FHIR имеет три level’а для «кодов» в зависимости от нужной точности.
code (primitive) — простая строка из закрытого enum, специфичного для данного поля. Используется когда value set маленький, фиксированный, и cross-system маппинг не нужен. Это primitive type, не data type.
"status": "final" // Observation.status: registered | preliminary | final | ...Coding (DataType) — структура { system, code, display, version? } — одиночный код из именованной кодовой системы.
{
"system": "http://loinc.org",
"code": "2093-3",
"display": "Cholesterol, Total"
}CodeableConcept (DataType) — обёртка вокруг массива Coding[] плюс free-text fallback:
{
"coding": [
{ "system": "http://loinc.org", "code": "2093-3", "display": "Cholesterol" },
{ "system": "http://snomed.info/sct", "code": "77068001", "display": "Cholesterol" }
],
"text": "общий холестерин"
}Зачем массив coding: одно и то же понятие можно одновременно закодировать в двух кодовых системах (LOINC + SNOMED) — это упрощает downstream consumer’у который понимает только одну. text — для human-readable fallback’а если все coding’и unfamiliar.
Правило большого пальца:
- Внутреннее поле статуса/типа с фиксированным enum →
code - Один код из стандарта (LOINC / SNOMED / RxNorm / ICD-10) →
Coding - Клинический концепт где может быть multi-coding или text fallback →
CodeableConcept
В FHIR-ресурсах подавляющее большинство «code»-полей — CodeableConcept, чтобы дать гибкость и multi-coding.
Reference — ссылка между ресурсами
Reference — DataType указывающий на другой ресурс4. Структура:
{
"reference": "Patient/123", // relative URL или absolute
"type": "Patient", // optional подтверждение типа
"identifier": { ... }, // optional — reference через identifier вместо URL
"display": "John Doe" // optional human-readable
}Форматы reference:
- Relative —
"Patient/123"(на том же FHIR-сервере) - Absolute —
"https://other-server.example.org/fhir/Patient/123"(внешний) - UUID —
"urn:uuid:b9a3d6a7-..."(только внутри Bundle для transactional resolution до server-assigned ID) - Versioned —
"Patient/123/_history/5"(привязка к конкретной версии)
Identifier-reference (логическая ссылка без URL) — { identifier: { system, value } }. Полезно когда target пока не создан в FHIR-store, но известен его business identifier (MRN, lab accession number). См. llm-fhir-linkback.
Contained resources — Patient.contained: [Resource] плюс reference: "#localId" для ссылки внутри родительского. Альтернатива для anonymous nested ресурсов без identity.
4. Universal slots на каждом ресурсе
Это не специфичные DataTypes, а mechanisms которые есть на любом Resource или элементе. Их две: meta (на уровне Resource — server/operational metadata) и extension (на любом элементе — custom-поля).
meta — server-side и operational metadata
Каждый Resource имеет meta-блок:
"meta": {
"versionId": "5", // server-assigned version
"lastUpdated": "2026-05-16T14:00:00Z", // server timestamp
"source": "https://bloodgpt.app", // origin URL
"profile": [ // claim conformance к этим профилям
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
],
"security": [ Coding ], // access control tags
"tag": [ Coding ] // operational tags (custom semantics)
}versionId/lastUpdated— сервер назначает, не клиентprofile— claim ресурса о соответствии конкретным профилям (fhir-profiling)security— access control (напримерconfidentiality,redaction)tag— operational metadata. Мы используем для origin tracking (source-chat/source-survey/source-document-import) — см. fhir-meta-tagging и fhir-resource-origin-and-lifecycle.
Extension — механизм custom-полей
Базовый ресурс не покрывает всё, что нужно конкретной экосистеме (custom-поля, специфичные для рынка / vendor / use case). FHIR имеет универсальный механизм extension — добавить custom поле через структуру { url, value[x] }5:
"extension": [
{
"url": "http://hospital.example.org/StructureDefinition/admission-channel",
"valueString": "emergency-room"
}
]url — каноническая ссылка на StructureDefinition extension’а (где описано что это за поле, какой тип, etc). value[x] — само значение (типизировано: valueString, valueDateTime, valueCodeableConcept, …).
Extensions могут быть standard (определены в HL7 или в realm-IG) или custom (locally-defined). Применяются на любом уровне — на ресурсе целиком, на элементе, или даже на DataType.
Наша политика — минимизировать extensions. Детали — zero-extensions-fhir. Полная механика profiling и extensions — fhir-profiling. Конкретные URL conventions для собственных extensions — extension-url-conventions.
5. Bundle — контейнер ресурсов
Bundle — особый Resource, который оборачивает группу других ресурсов6. Семантика зависит от Bundle.type:
| Type | Смысл |
|---|---|
transaction | Атомарный batch CRUD — сервер применяет всё или ничего. Resolve внутренних UUID-ссылок. |
batch | Неатомарный batch CRUD — каждый entry независим, failures одного не блокируют другие. |
document | Фиксированная структура: первый entry — Composition, дальше — referenced ресурсы. Документ-как-целое. Подпись через Bundle.signature. |
collection | Bag of resources без специфической семантики — просто группа. |
searchset | Server response на search — entries это matching ресурсы + included. |
history | Server response на history-операцию — versions ресурса. |
message | Async messaging — первый entry это MessageHeader. |
В нашем стеке мы используем в основном transaction (атомарный POST множества ресурсов из одного analysis run — Composition + Observations + AllergyIntolerances + и т.п.) и searchset (server output). См. fhir-bundle для production-deep dive.
Связано
- fhir-basics — введение в FHIR через метафору карточек и связей между ними
- fhir-resource-categories-overview — модули FHIR + альтернативный взгляд по скорости изменения
- fhir-bundle — production-deep dive по Bundle (transaction-семантика, UUID resolution)
- fhir-conformance-resources — meta-ресурсы которые формально описывают сами elements (StructureDefinition / ValueSet)
- fhir-profiling — как накладывать constraints на elements через StructureDefinition profiles
- zero-extensions-fhir — наша политика по extensions — active
- extension-url-conventions — URL conventions для собственных extensions — draft
- fhir-meta-tagging — конкретный use case
meta.tag(origin tracking) - fhir-resource-origin-and-lifecycle — где живёт
meta.tagв нашем pipeline - domain-driven-design — Resource ≈ Entity, DataType ≈ Value Object параллель
Сноски
-
HL7 FHIR R4 — Element type (base class), accessed 2026-05-19, https://hl7.org/fhir/R4/element.html. ↩
-
HL7 FHIR R4 — Cardinality concepts, accessed 2026-05-17, https://www.hl7.org/fhir/conformance-rules.html. ↩
-
HL7 FHIR R4 — DataTypes overview, accessed 2026-05-17, https://www.hl7.org/fhir/datatypes.html. ↩
-
HL7 FHIR R4 — References between resources, accessed 2026-05-17, https://www.hl7.org/fhir/references.html. ↩
-
HL7 FHIR R4 — Extensibility (extension mechanism), accessed 2026-05-19, https://hl7.org/fhir/R4/extensibility.html. ↩
-
HL7 FHIR R4 — Bundle, accessed 2026-05-17, https://www.hl7.org/fhir/bundle.html. ↩