FHIR Shorthand (FSH, читается «фиш») — это текстовый DSL для авторства FHIR conformance-ресурсов: profiles, extensions, value sets, code systems. Альтернатива тому чтобы писать StructureDefinition руками в JSON. Компилируется компилятором SUSHI в стандартный JSON, который потом обрабатывают все остальные FHIR-tool’ы.

Создан 2020 в рамках HL7, для решения проблемы «writing JSON SDs by hand is unbearable, Forge GUI editor is fine but not diffable, нужен plain-text source с конвенциями из mainstream разработки». Стабилизирован 2021.

Где живёт в данных

  • FSH-файлы (*.fsh) живут в исходниках IG-репозитория (обычно input/fsh/).
  • При билде SUSHI читает их и эмитит JSON в fsh-generated/resources/.
  • Дальше IG Publisher / FHIR-сервер работают с JSON.
  • В runtime FHIR-server FSH не существует — это исключительно author-time артефакт.

Синтаксис

Каждый FSH-файл — это набор top-level declarations, разделённых пустой строкой.

Profile

Profile: BloodGPTComposition
Parent: Composition
Id: bloodgpt-composition
Title: "BloodGPT Test Overview Composition"
Description: "Контейнер для AI-сгенерированного narrative по анализу крови"
 
* status 1..1 MS
* status = #final                          // fixed value (# = code prefix)
* type 1..1 MS
* type from BloodGPTCompositionTypeVS (required)
* subject 1..1 MS
* subject only Reference(Patient)
* author 1..* MS
* section 4..5

Каждая строка начинающаяся с * — это rule. Синтаксис: * <path> <cardinality> <flags> или * <path> = <fixed value> или * <path> from <ValueSet URL> (<binding strength>).

Extension

Extension: RequiresDoctorPreparation
Id: requires-doctor-preparation
Context: Composition
* value[x] only boolean
* value[x] 1..1 MS

ValueSet

ValueSet: BloodGPTBiomarkerVS
Id: bloodgpt-biomarker
Title: "BloodGPT supported biomarkers"
* http://loinc.org#2160-0  "Creatinine"
* http://loinc.org#2345-7  "Glucose"
* http://loinc.org#1751-7  "Albumin"

CodeSystem

CodeSystem: SectionType
Id: bloodgpt-section-type
* #test-overview        "Test Overview"          "Главный narrative по результату анализа"
* #panel-overviews      "Panel Overviews"        "Описание каждой панели биомаркеров"
* #follow-up            "Follow-Up Recommendations"
* #parameter-details    "Parameter Details"
* #trends               "Trends"

Slicing — типизация повторяющихся полей

Самая громоздкая часть FSH (как и в JSON SD):

* code.coding ^slicing.discriminator.type = #value
* code.coding ^slicing.discriminator.path = "system"
* code.coding ^slicing.rules = #open
* code.coding contains
    loinc 1..1 MS and
    snomed 0..1
* code.coding[loinc].system = "http://loinc.org"
* code.coding[snomed].system = "http://snomed.info/sct"

Read как: «массив coding разрезаем по system, требуем что внутри есть один coding с system=LOINC (обязательно), и опционально может быть один с system=SNOMED».

Комментарии

// Строчный комментарий
/* Блочный
   комментарий */
 
Profile: X
Parent: Y
// Объясняем почему сделали 1..1
* foo 1..1 MS

В compiled JSON комментарии не попадают.

SUSHI — компилятор FSH → JSON

CLI-tool на Node.js (npm install -g fsh-sushi). Запускается из корня IG-репо:

sushi build .

Читает input/fsh/**/*.fsh, валидирует синтаксис и логику (например что cardinality сужает, а не расширяет родительский ресурс), эмитит JSON в fsh-generated/resources/StructureDefinition-*.json, ValueSet-*.json, и т.д.

Полный pipeline IG-разработки:

*.fsh (FSH source)
  ↓ sushi build
*.json (StructureDefinition, ValueSet, ...)
  ↓ IG Publisher
HTML IG site + NPM package + validation pack

См. fhir-implementation-guide для того что делает IG Publisher.

Когда FSH используется и когда нет

Используют FSH:

  • Современные IG’и (с 2021+): mCODE, Da Vinci HRex, ряд региональных core IGs (HL7 BE, IPS отдельные modules)
  • Команды переходящие с Forge / ручного JSON на text-based workflow
  • Любой кто хочет diff-friendly source + ChatGPT-friendly формат

Не используют FSH (пишут JSON напрямую):

  • US-Core — крупнейший US IG, пишет SDs прямо в JSON (input/resources/StructureDefinition-*.json). В репо HL7/US-Core 0 файлов с расширением .fsh1 — поисковый запрос gh api search/code?q=repo:HL7/US-Core+extension:fsh возвращает total_count: 0. Причина историческая: US-Core старше FSH (US-Core начал 2018, FSH стабилизирован 2021), и миграция не выполнена.
  • Часть legacy IG’ов с 2017–2019 — тоже на JSON
  • IG’и с автогенерацией SDs из другой нотации (YAML, TypeScript) — например input/resources-yaml/ у US-Core содержит YAML, который 1:1 mirrors JSON

Выбор IG-команды, а не обязательное требование. Compiled JSON одинаков и в том и в другом случае. FSH — это convention, не часть FHIR-стандарта.

Tooling экосистема

  • SUSHIfhir/sushi, Node CLI, official HL7-supported компилятор
  • VS Code extension — синтакс-подсветка, snippets, validation
  • IntelliJ plugin — то же для JetBrains
  • GoFSH — обратный путь: JSON SD → FSH (для миграции существующих IGs на FSH)
  • fsh.tools — online playground для проверки snippets

Failure modes

  • SUSHI требует Node ≥18 — в Docker-builds иногда конфликтует с pinned версиями
  • Cardinality можно ослабить случайно через ^element.min = 0 — SUSHI ловит, но через cryptic warning’и
  • Slicing rules — самая сложная часть FSH, ошибки в discriminator path не всегда дают понятную ошибку компиляции
  • FSH версионируется (FSH 1.x, FSH 2.0), но синтаксические изменения редкие; основная backward compatibility держится

Открытые вопросы

  • Если мы будем формализовать profiling — пишем FSH или JSON? FSH удобнее для авторства, JSON ближе к runtime артефакту. Большинство современных команд выбирают FSH; см. formalize-fhir-profiles для нашего выбора.
  • Нужен ли нам SUSHI как dependency в monorepo, или вынести IG-разработку в отдельный репо bloodgpt-fhir-profiles?

Связано

  • fhir-conformance-resources — что собственно описывают FSH-файлы (StructureDefinition / ValueSet / CodeSystem)
  • fhir-profiling — основное применение FSH (writing profiles)
  • fhir-implementation-guide — следующий шаг pipeline’а (JSON → IG)
  • fhir-code-generation — generated TS types / Zod из тех же SDs которые писали в FSH
  • us-core — пример IG который НЕ использует FSH (пишут JSON напрямую)
  • formalize-fhir-profiles — наше решение использовать ли FSH у себя — draft

Сноски

  1. GitHub Code Search repo:HL7/US-Core extension:fsh, accessed 2026-05-19, https://github.com/search?q=repo:HL7/US-Core+extension:fsh&type=code — возвращает 0 результатов, подтверждая что US-Core не использует FSH. Цит. по сессии ildar/691257df.