文章 Lilian Huang · 2 hr 前 13m read

在 IRIS 上配置 FHIR Profile

什么是 FHIR Profile?

FHIRProfile是规则和约束的集合,用于定制和完善基础快速医疗互操作性资源 (FHIR) 资源(resource。Profiling是一个重要的过程,它可以调整基础 FHIR 资源标准,以满足特定用例、地理区域、医疗机构或临床工作流程的独特要求。

基础 FHIR 规范为资源(如病人、观察或药物)提供了通用、灵活的定义,而Profiling则将这些通用资源转化为更精确的资源。这就确保了为特定社区或实施量身定制的数据交换的一致性和互操作性。

FHIR 旨在覆盖全球各种医疗保健场景。配置文件允许实施者在不丧失标准化优势的情况下调整这一通用平台。

 

什么时候用到FHIR Profiles

FHIR profiles系统用于验证数据的可计算规则。当您需要确保交换的数据不仅在技术上有效,而且在临床上相关,并符合特定任务的当地法规时,您就应该使用它们。

FHIR profiles用例

FHIR RESTful API 有两种主要方法来声明FHIR profiles的用途

1.通过 Query Parameter (?_profile 或 $validate)

  1. _profile = 搜索过滤器 (不用于验证,但对检索存储的资源有效)。仅用于 搜索 已声称符合要求的资源例如

GET /Patient?_profile=http://example.org/fhir/StructureDefinition/MyProfile

错误:/Patient/$validate?_profile=http://example.org/fhir/StructureDefinition/MyProfile

  1. $validate = 验证操作(用于配置文件验证是正确的,它是 $validate 操作的一个操作参数。)它用于要求服务器 根据特定配置文件验证资源例如

POST /Patient/$validate?profile=http://example.org/fhir/StructureDefinition/MyProfile

  1. IRIS 特定验证 --InterSystems IRIS 要求 在执行 $validate 时提供版本号例如

POST /Patient/$validate?profile=http://examples.com/fhir/StructureDefinition/aktestpatient|1.0.0

请注意 without the version number, IRIS returns an error:

"配置文件 URI ......不包括版本号。版本号是配置文件验证所必需的"。

注: 标准 FHIR 允许使用不含版本号的规范 URL,但 IRIS 为确保确定性和安全性而强制执行。

2.通过 Resource Content (meta.profile) [首选]

您可以在资源本身中指定profile

{
	"resourceType": "Patient",
	"meta": {
		"profile": [
			"http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
		]
	}
}

用于Profiling的关键 FHIR Artifacts

1.StructureDefinition(Profile本身)

StructureDefinition 资源是 FHIR Profile的核心工件。它是数据必须遵循的蓝图或模式。它描述了资源或数据类型的规则和约束,并指明了下一步:

  • 必填或可选字段。
  • Cardinality(最小/最大重复次数)。
  • 固定值或模式。
  • 允许的术语(值集)。
  • 适用扩展。

关键内容:

  • url(规范 URL): 资源实例的meta.profile中使用的稳定、唯一标识符
  • baseDefinition(基本定义):指向受限资源(或配置文件)的链接。
  • 快照:资源的全面、"扁平化 "视图,包含应用的所有限制。
  • 差异:应用于基本定义的更改或限制的列表(由配置文件创建者确定)。

2.值集

它规定了字段的一组允许代码

  • 目的: 指明 特定元素允许使用的值

3.代码系统

它定义了代码列表及其含义(本质上是一个字典)。

  • 目的: 为值集提供构建模块。
  • 关系
    • CodeSystem = "所有可能的代码
    • ValueSet = "用于此配置文件的子集

4.操作定义

描述对 FHIR 资源的自定义操作或功能

  • 它是可选的,仅用于特殊端点(如 $submit、$calculate-risk、$aggregate)。

5.扩展

FHIR 资源有一个固定的模式,遵循 80/20 规则(预定义了最常用的元素)。

  • 扩展提供了一种 安全、标准化的方式来添加 基本资源中不存在的字段
  • 扩展使用结构定义(StructureDefinition)进行定义,类型设置为 "复杂类型 "或 "数据类型"。

扩展类型:

  1. 简单扩展: 它是一个单独的值(如 valueString、valueBoolean、valueDate)。
  2. 复杂扩展: 由嵌套元素组成,类似于迷你资源。

举例说明: 为病人添加国籍:

{
  "resourceType": "Patient",
  "id": "123",
  "extension": [
    {
      "url": "http://example.org/fhir/StructureDefinition/patient-nationality",
      "valueString": "Indian"
    }
  ]
}

不识别扩展名的服务器 可以安全地忽略它。

需要扩展名的简介示例如下:

{
  "id": "Patient.nationality",
  "path": "Patient.extension",
  "sliceName": "patientNationality",
  "min": 1,
  "max": "1",
  "type": [
    {
      "code": "Extension",
      "profile": [
        "http://example.org/fhir/StructureDefinition/patient-nationality"
      ]
    }
  ]
}

StructureDefinition 示例:

 

扰流板(Spoiler)

FHIR 扩展:最佳实践

虽然 FHIR 资源有固定的结构,但实际实施中往往需要额外的数据字段。 扩展(Extensions) 提供了在不修改基础资源的情况下添加这些额外信息的标准化方法。为保持互操作性并避免不必要的复杂性,请遵循以下列出的最佳实践:

  1. 创建前重复使用 - 首先,检查是否已经存在社区认可的合适扩展。
  2. 仅在必要时创建新扩展 - 仅在现有字段或扩展无法满足要求时才生成自定义扩展。
  3. 保持扩展的 简单性和模块性 - 尽可能选择简单的扩展(如 valueString、valueDate、valueBoolean)。只有在需要时才使用复杂的扩展。
  4. 记录和共享 - 在 StructureDefinition 中明确定义扩展 ,并提供示例供他人理解和重用。

FHIR Profile文件切分(摘要与示例)

在 FHIR 中,资源的某些元素可以重复使用(如 Patient.identifier 或 Observation.component)。分片是一种机制,可让您对重复元素的不同子集应用不同的规则或约束(每个分片都 根据自己的规则进行独立验证 )。 例如,病人可能有多个标识符:社会安全号 (SSN) 和医疗记录号 (MRN)。如果不进行分片,只能对所有标识符执行通用规则,但无法区分类型或应用单独的约束。有了切分功能,就可以将每种类型的标识符定义为不同的 "切片",并拥有自己的卡片性、数据类型和固定值。

  • 要点
    • 每个片段都有自己的 sliceName、cardinality(最小/最大)和约束条件(ValueSets、固定代码等)。
    • 单值元素(最大值=1)不需要分片,因为可以直接在差分中应用约束。

病人资料的切分定义示例如下:

[
	{
		"id": "Patient.identifier",
		"path": "Patient.identifier",
		"sliceName": "ssn",
		"min": 1,
		"max": "1",
		"type": [
			{
				"code": "Identifier"
			}
		],
		"fixedSystem": "http://hl7.org/fhir/sid/us-ssn"
	},
	{
		"id": "Patient.identifier",
		"path": "Patient.identifier",
		"sliceName": "mrn",
		"min": 0,
		"max": "1",
		"type": [
			{
				"code": "Identifier"
			}
		],
		"fixedSystem": "http://hospital.org/mrn"
	}
]

FHIR Profile中的约束和值集绑定

在 FHIR 配置文件中,多个元素使用编码值,例如 Patient.gender 或 Observation.code。虽然基本 FHIR 规范可能已经定义了允许的代码,但配置文件可以 进一步限制这些值 ,以满足特定用例、区域或组织规则的要求。要做到这一点,可以将元素绑定到定义了允许代码集的 ValueSet 上,也可以指定绑定强度(必填、可扩展或首选)来控制必须严格遵守代码的程度。

例如,Patient.gender(病人性别)字段在全球范围内允许四种代码:男性、女性、其他和未知。本地系统可以选择只接受男性或女性。在配置文件的帮助下,您可以将 Patient.gender 与一个 ValueSet 绑定,该 ValueSet 仅包含这两个代码,并具有所需的绑定强度。这将确保任何未使用允许代码之一的资源无法通过配置文件验证。

配置文件中的绑定示例:

{
  "id": "Patient.gender",
  "path": "Patient.gender",
  "min": 1,
  "max": "1",
  "type": [{ "code": "code" }],
  "binding": {
    "strength": "required",
    "valueSet": "http://example.org/fhir/ValueSet/local-gender"
  }
}

FHIR Profile中的 Cardinality

Cardinality 定义了 元素(Element) 在资源中出现的次数。 它由配置文件差值中的 min(最小)和 max(最大)值指定。

  • min → 元素必须出现的最少次数。
  • max → 元素出现的最大次数。使用 "*"表示无限制重复
{
  "id": "Patient.telecom",
  "path": "Patient.telecom",
  "min": 0,
  "max": "*"
}

FHIR Profile层次结构和继承

FHIR Profile不必只限制基础资源。它们也可以 建立在其他现有预案的基础上。这意味着一个预案可以 继承 另一个预案 的所有规则、约束和绑定 ,然后 为特定用例 添加额外的要求 。这种分层方法有助于促进 重复使用、一致性和模块化设计

例如, US-Core-Patient 配置文件定义了姓名和性别等必填字段。医院可以创建一个 自定义配置文件 ,在 US-Core-Patient 的基础上添加国家标识符或保险信息。通过将 US-Core-Patient 设置为其 baseDefinition,自定义配置文件将自动继承基础配置文件的所有约束,同时也会执行自己的附加规则:

{
  "resourceType": "StructureDefinition",
  "url": "http://example.org/fhir/StructureDefinition/HospitalPatient",
  "name": "HospitalPatient",
  "status": "draft",
  "fhirVersion": "4.0.1",
  "kind": "resource",
  "abstract": false,
  "type": "Patient",
  "baseDefinition": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient",
  "derivation": "constraint",
  "differential": {
    "element": [
      {
        "id": "Patient.identifier",
        "path": "Patient.identifier",
        "sliceName": "nationalId",
        "min": 1,
        "max": "1",
        "type": [{"code": "Identifier"}],
        "fixedSystem": "http://example.org/fhir/sid/national-id"
      }
    ]
  }
}

baseDefinition "字段决定了 您的profile所约束的配置文件或资源,从而创建了 层次或继承关系。这意味着您的 HospitalPatient 配置文件 从 US-Core-Patient 配置文件继承所有约束

使用参数与直接资源验证 $validate

FHIR 标准允许 $validate 操作以 两种方式接受资源 直接在 POST 主体中封装在参数资源。参数资源是一种标准的 FHIR 资源类型,旨在将命名的输入值传递给操作。 对于简单的验证,使用 参数资源可选的 ,但在需要多个参数时(例如,指定配置文件版本、验证模式或附加输入),建议使用 参数资源

示例 - 直接资源:

POST /Patient/$validate?_profile=...|1.0.0
Content-Type: application/fhir+json

{
  "resourceType": "Patient",
  "id": "123",
  "name": [{"family": "Doe", "given": ["John"]}],
  "gender": "male"
}


示例 - 参数封装器(建议灵活使用):

{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "resource",
      "resource": { "resourceType": "Patient", "id": "123", "name": [{"family": "Doe", "given": ["John"]}], "gender": "male" }
    }
  ]
}
{
  "resourceType": "StructureDefinition",
  "url": "https://example.org/fhir/StructureDefinition/TutorialPatient",
  "name": "TutorialPatient",
  "status": "draft",
  "version": "1.0.1",
  "fhirVersion": "4.0.1",
  "kind": "resource",
  "abstract": false,
  "type": "Patient",
  "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
  "derivation": "constraint",
  "differential": {
    "element": [
      { "id": "Patient.identifier", "path": "Patient.identifier", "min": 1 },
      { "id": "Patient.name", "path": "Patient.name", "min": 1 },
      { "id": "Patient.gender", "path": "Patient.gender", "min": 1 },
      { "id": "Patient.birthDate", "path": "Patient.birthDate", "min": 1 }
    ]
  }
}

IRIS 支持这两种方法。使用 "参数 "封装器可确保 在需要额外参数时,具有面向未来的灵活性

在 InterSystems IRIS 中实施 FHIR Profile

在 InterSystems IRIS 中实施 FHIR Profile 的前提条件

在开始实施 FHIR Profile 之前,请确保您的环境符合以下要求和架构限制:

  • 版本兼容性:配置文件验证目前针对 FHIR R4 进行了优化。计划在未来版本中支持 FHIR R5。
  • 运行环境:系统必须安装 Java 11。这是对 FHIR 资源执行验证逻辑的严格要求。
  • 服务配置:FHIR 验证服务器必须处于激活状态。该组件对于在 IRIS 生态系统内处理和验证配置文件至关重要。

将 FHIR Profiles导入 InterSystems IRIS

在执行资源验证之前,必须先将相关的 FHIR Profiles导入 IRIS 平台。为确保成功导入,您的配置文件包必须遵守特定的目录结构。

Profile 包结构

导入实用程序要求两个关键文件位于 同一目录

  1. package.json:该清单文件决定了 FHIR Profile的元数据、依赖关系和版本。
  2. StructureDefinition:该文件(JSON 格式)包含您正在定义的 FHIR 资源的实际约束和规则。

注意: 这两个文件都是必须的。如果 package.json 和 StructureDefinition 文件未一起存储在同一源文件夹中,导入过程将失败。

package.json:

{
  "name": "finalpatient.profile",
  "version": "1.0.0",
  "description": "Example finalpatient snapshot profile validation package",
  "dependencies": {
    "hl7.fhir.r4.core":"4.0.1"
  }
}


StructureDefinition:

 

扰流器

{
	"resourceType": "StructureDefinition",
	"id": "FinalPatient",
	"url": "http://example.org/fhir/StructureDefinition/FinalPatient",
	"version": "1.0.0",
	"name": "FinalPatient",
	"status": "active",
	"fhirVersion": "4.0.1",
	"kind": "resource",
	"abstract": false,
	"type": "Patient",
	"baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
	"derivation": "constraint",
	"text": {
		"status": "generated",
		"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Profile for patients with mandatory identifier, name, and gender.</div>"
	},
	"snapshot": {
		"element": [
			{
				"id": "Patient",
				"path": "Patient",
				"min": 0,
				"max": "*",
				"short": "Demographics and administrative information for an individual",
				"definition": "Demographics and other administrative information about an individual or animal receiving care or other health-related services.",
				"base": {
					"path": "Patient",
					"min": 0,
					"max": "*"
				}
			},
			{
				"id": "Patient.identifier",
				"path": "Patient.identifier",
				"min": 1,
				"max": "*",
				"short": "An identifier for this patient",
				"definition": "An identifier for this patient: a medical record number, resource identifier, international patient identifier, social security number, etc. **(CONSTRAINT: REQUIRED)**",
				"type": [
					{
						"code": "Identifier"
					}
				],
				"base": {
					"path": "Patient.identifier",
					"min": 0,
					"max": "*"
				}
			},
			{
				"id": "Patient.name",
				"path": "Patient.name",
				"min": 1,
				"max": "*",
				"short": "A name associated with the patient",
				"definition": "A name associated with the patient. **(CONSTRAINT: REQUIRED)**",
				"type": [
					{
						"code": "HumanName"
					}
				],
				"base": {
					"path": "Patient.name",
					"min": 0,
					"max": "*"
				}
			},
			{
				"id": "Patient.gender",
				"path": "Patient.gender",
				"min": 1,
				"max": "1",
				"short": "male | female | other | unknown **(CONSTRAINT: REQUIRED)**",
				"definition": "Administrative Gender - the gender that the patient is legally considered to have or that should be used for administrative purposes.",
				"type": [
					{
						"code": "code"
					}
				],
				"binding": {
					"strength": "required",
					"valueSet": "http://hl7.org/fhir/ValueSet/administrative-gender"
				},
				"base": {
					"path": "Patient.gender",
					"min": 0,
					"max": "1"
				}
			}
		]
	}
}

逐步进行:导入 FHIR Profile

准备并整理好软件包文件后,在管理门户 (SMP) 中按照以下步骤将配置文件导入 InterSystems IRIS 环境:

导航路径

  1. 打开管理门户:登录并导航至 "Health "部分。
  2. 选择您的命名空间:选择配置 FHIR 服务器的特定命名空间。
  3. 访问 FHIR 配置:转到 "FHIR 服务器管理">"软件包管理"(FHIR Server Management > Package Management)
  4. 进入 "软件包管理(Package Management) "控制面板后,执行以下操作:
  5. 单击导入:选择导入(Import)按钮。
  6. 指定来源:将系统指向包含 package.json 和 StructureDefinition 文件的目录。
  7. 确认:完成向导,将定义加载到实例中。

导入完成后,检查 "包管理(Package Management) "列表。您的新profile应出现在 FHIR 核心软件包下:

Profiles与 FHIR 端点关联起来

将软件包导入 InterSystems IRIS 可使系统获得定义,但不会自动将其应用到 FHIR 端点。要启用配置文件验证,您必须手动将导入的软件包链接到特定端点。

选项 A:更新现有端点

如果已经配置了 FHIR 端点,请按照以下步骤添加配置文件:

  1. 导航至设置:打开端点配置并单击 "编辑"。
  2. 选择包:找到 "自定义包(Custom Packages) "部分。从列表中选择之前导入的软件包。
  3. 应用更改:单击保存。

注意:单击保存后请耐心等待。系统索引新定义和更新端点元数据可能需要一些时间。

选项 B:创建新端点

如果您正在设置一个新的 FHIR 服务,请执行以下步骤:

  1. 配置基础知识:填写端点 URL 和核心设置。
  2. 添加自定义定义:在首次单击保存之前,请导航到 "自定义包(Custom Packages) "字段并选择您导入的包。
  3. 最终确定:保存端点,使用已就位的配置文件定义对其进行初始化。

根据 FHIR Profile验证资源

导入软件包并成功链接到端点后,您的环境现在已经完全配置好了。您可以开始根据自定义配置文件验证 FHIR 资源。

执行验证

现在,您可以使用 $validate 操作向 FHIR 端点发送 POST 请求。服务器将采用您的 StructureDefinition 中定义的规则,确保传入的资源符合您的特定业务逻辑和数据要求。

开始使用示例代码

您可以在此fhir-profile-demorepo 中找到完整的代码库和随时可用的示例。克隆该 repo,以便在自己的 IRIS 环境中快速测试配置文件导入和验证流程