URL — это canonical identifier для каждого FHIR conformance-ресурса. Он попадает в meta.profile, в extension[].url, в дочерние SDs которые ссылаются друг на друга, в IG references. Менять URL после публикации больно (downstream consumers держат старый), поэтому выбрать convention лучше до того как начнём активно профилировать.
Status: draft
Решение ещё не принято. Сейчас в коде сосуществуют две конвенции — это carry-over из времени когда extensions добавляли ad-hoc.
Контекст
В коде BloodGPT (см. zero-extensions-fhir.md — раздел «Текущее состояние») сейчас используются:
http://bloodgpt.com/fhir/StructureDefinition/<name>— напримерrequires-doctor-preparation,bloodgpt-parameter-analysishttp://bloodgpt.com/fhir/extension/<name>— напримерoriginal-name,extraction-source
Обе указывают на одинаковые по сути артефакты — наши extensions. Разный путь — историческая случайность.
Дополнительно: при формализации профайлинга появятся URL’ы для самих profiles (наш Composition / Observation / ClinicalImpression) — и для CodeSystems / ValueSets. Convention должен покрывать все эти случаи.
Рассматривали
(A) http://bloodgpt.com/fhir/StructureDefinition/<name> — единый namespace для всех SDs
Все extensions, profiles, value sets, code systems — под одним subroot /fhir/. Разделение по типу SD — через resourceType внутри JSON, не через URL path.
За:
- Совпадает с HL7 conventions (
http://hl7.org/fhir/StructureDefinition/Patient,http://hl7.org/fhir/ValueSet/observation-category) — родной паттерн FHIR-инструментов - IG Publisher по умолчанию ожидает именно такую структуру
- При publish’е через simplifier.net / npm — URL’ы устаканиваются без переименования
- Большинство существующих в коде extensions УЖЕ так названы (
bloodgpt.com/fhir/StructureDefinition/...)
Против:
- Длиннее (
StructureDefinition— 19 символов в path) - Для людей не сразу понятно «это extension или profile», нужно открыть JSON
(B) http://bloodgpt.com/fhir/extension/<name> + http://bloodgpt.com/fhir/profile/<name> — разделение по типу
Разные subroot для разных классов SDs: extension/, profile/, valueset/, codesystem/.
За:
- Самодокументируется — URL сразу говорит что это extension vs profile
- Короче (
extension/fooкороче чемStructureDefinition/foo) - Знакомо для людей с не-FHIR background
Против:
- Расходится с HL7 conventions — IG Publisher / валидаторы могут давать warnings или требовать настройки
- При publish’е на simplifier.net — URLs ребрендятся (simplifier ожидает
StructureDefinition/) - Lock-in в наш custom layout, migration к standard pattern позже дорогой
- Часть текущих extensions придётся переименовать (с
StructureDefinition/→extension/)
(C) Гибрид — оставить как есть, не унифицировать
Каждый extension живёт по тому URL’у, по которому его прописали изначально. Новые extensions именуются по-разному.
За:
- Не требует миграции существующих ресурсов
- Не ломает FHIR-store (где
meta.profileссылается на старые URL’ы)
Против:
- Хаос для downstream-consumers — два URL pattern’а под одинаковую семантику
- Невозможно сгенерировать IG (IG Publisher не примет смешанные conventions)
- Каждый новый extension — отдельное решение «куда класть»; растёт энтропия
Выбрали: (не решено)
Склонность есть к (A) — стандартный HL7 pattern, минимальный future migration. Один namespace, всё под StructureDefinition/<name>. Включая extensions (потому что extensions это StructureDefinition с type: Extension).
Это потребует миграции существующих extensions на bloodgpt.com/fhir/extension/<name> → bloodgpt.com/fhir/StructureDefinition/<name>. Список из zero-extensions-fhir.md:
original-name,extraction-source,trending-group-id— сейчас под/extension/, нужно перенестиrequires-doctor-preparation,bloodgpt-parameter-analysis,source-diagnostic-report— уже под/StructureDefinition/, не трогать
Что нужно для разрешения
- Подтвердить через grep: точный список extensions в коде с какой текущий URL pattern (carry-over из zero-extensions-fhir — «полная инвентаризация»)
- Проверить migration cost: если ресурсы с
meta.profileилиextension.urlстарого pattern’а уже лежат в FHIR-store — нужен ли rewrite, или мы можем просто прекратить писать новые с старым URL? - Решить про CodeSystem / ValueSet — туда же под
bloodgpt.com/fhir/CodeSystem/<name>/ValueSet/<name>или короче
Следствия
- Какой бы вариант ни выбрали — нужно зафиксировать в wiki convention для FHIR-URLs в footnote’ах
- При формализации профайлинга (formalize-fhir-profiles) URL convention — первое что фиксируется
- Codegen-инструменты (fhir-code-generation) используют URL как часть generated typename; смена URL = смена generated typename
Открытые вопросы
- Что делать с уже записанными в FHIR-store ресурсами, у которых extension URL сейчас по старому pattern’у? Если миграция (Variant A) — нужен migration script через
$updateдля тысяч ресурсов - Может ли FHIR-store держать дубль
meta.profile(старый URL + новый) во время transition period? - Нужен ли URL versioning (
bloodgpt.com/fhir/StructureDefinition/v1/foovsv2/foo) или достаточноversion:field внутри SD?
Связано
- zero-extensions-fhir — где живёт carry-over с инвентаризацией extensions — active
- formalize-fhir-profiles — крупное решение «писать ли свои SDs» — draft; URL convention — sub-decision внутри него
- fhir-profiling — общая механика StructureDefinition
- fhir-conformance-resources — что в URLs ссылается (SD / VS / CS)
- fhir-implementation-guide — где URLs становятся canonical при публикации IG