Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
如何使用 FHIR R4 存储病历
教程:创建 Patient、血压 Observation 和 Condition,使用事务,搜索,通过历史记录更新并读取数据溯源——每次请求都附带 curl 命令和实际响应,在免费沙盒上进行。
本教程将 HL7 FHIR R4 资源存储为一个小型医疗记录:一个 Patient,一个血压 Observation 和一个诊断作为 Condition,然后将患者和测量结果一起放入一个事务中。它会搜索它们,在不丢失早期版本的情况下更新诊断,并读取谁写了什么。 每个请求都是直接针对免费 Anpheros 沙盒的 curl,并且显示的每个响应都是 API 返回的内容。
如果您是 FHIR 新手,请先阅读 FHIR 平台 以了解概念。本页是实践部分。
大多数记录的起始三个资源
| 资源 | 包含内容 | 编码方式 |
|---|---|---|
Patient |
记录的主体:姓名、出生日期、性别、其他系统的标识符 | 您的标识符系统 |
Observation |
任何测量或报告的内容:生命体征、实验室结果、体重、症状评分 | LOINC, UCUM 单位 |
Condition |
诊断或健康问题,及其随时间的变化状态 | ICD-10 (SNOMED CT 在许可标志后) |
药物 (MedicationStatement)、过敏 (AllergyIntolerance)、免疫接种和文档遵循相同的模式;26 种支持的资源类型 列在 /fhir/R4/metadata 的能力声明中。
开始之前
在 platform.anpheros.com/dashboard 使用 获取沙盒密钥 获取一个沙盒密钥 (sk_test_…)。您在那里创建的任何内容都不是真实的患者数据,并且对其他项目不可见。
export BASE=https://platform.anpheros.com/fhir/R4
export KEY=sk_test_…
步骤 1:创建患者
curl -X POST "$BASE/Patient" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" -d '{
"resourceType": "Patient",
"identifier": [{"system": "https://clinic.example/mrn", "value": "MRN-10442"}],
"name": [{"family": "Marin", "given": ["Ioana"]}],
"gender": "female",
"birthDate": "1979-04-12"
}'
201 Created,并附带服务器分配的 id 和版本:
{"resourceType": "Patient",
"identifier": [{"system": "https://clinic.example/mrn", "value": "MRN-10442"}],
"name": [{"family": "Marin", "given": ["Ioana"]}], "gender": "female", "birthDate": "1979-04-12",
"id": "d09e3942-ed86-4458-b099-fa674ab21b84",
"meta": {"versionId": "1", "lastUpdated": "2026-10-12T20:16:51.043Z"}}
在 identifier 中保留您自己的 id,并使用您控制的 system(此处为诊所的记录编号),以便您始终可以使用 GET $BASE/Patient?identifier=https://clinic.example/mrn|MRN-10442 再次找到该患者。FHIR id 是平台的,并且特定于您的项目:另一个项目会看到同一个人,但使用不同的 id。
export PID=d09e3942-ed86-4458-b099-fa674ab21b84
步骤 2:将测量值存储为 Observation
血压是一个具有两个组成部分(收缩压和舒张压)的 Observation,每个组成部分都有自己的 LOINC 代码。说明谁进行了测量:此处为家用设备。
curl -X POST "$BASE/Observation" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
-H "X-Anpheros-Author-Type: device" -H "Idempotency-Key: bp-2026-10-10-0830" -d '{
"resourceType": "Observation",
"status": "final",
"category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
"code": {"coding": [{"system": "http://loinc.org", "code": "85354-9", "display": "Blood pressure panel"}]},
"subject": {"reference": "Patient/'$PID'"},
"effectiveDateTime": "2026-10-10T08:30:00Z",
"component": [
{"code": {"coding": [{"system": "http://loinc.org", "code": "8480-6"}]},
"valueQuantity": {"value": 138, "unit": "mmHg", "system": "http://unitsofmeasure.org", "code": "mm[Hg]"}},
{"code": {"coding": [{"system": "http://loinc.org", "code": "8462-4"}]},
"valueQuantity": {"value": 88, "unit": "mmHg", "system": "http://unitsofmeasure.org", "code": "mm[Hg]"}}
]
}'
响应是已存储的资源,包含 id 和 meta.versionId: "1"。三个细节对于可用的记录很重要:
- 代码,而非标签。
85354-9在所有 FHIR 系统中都表示“血压面板”;而自由文本“BP”则不表示。使用GET /v1/terminology/loinc?q=blood pressure(FHIR 代码系统) 查找代码。 - UCUM 单位(
mm[Hg]、kg、mg/dL)在valueQuantity.code中,以便可以比较和转换值。 Idempotency-Key。 超时后的重试会返回第一个响应,而不是重复存储读数。
实验室结果是相同的资源,包含 category、laboratory,通常还有一个 referenceRange。要将完整的实验室报告导入,请参阅 如何将实验室结果导入 FHIR 记录。
步骤 3:将诊断记录为 Condition
curl -X POST "$BASE/Condition" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
-H "X-Anpheros-Author-Type: practitioner" -d '{
"resourceType": "Condition",
"subject": {"reference": "Patient/'$PID'"},
"clinicalStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "active"}]},
"verificationStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status", "code": "confirmed"}]},
"code": {"coding": [{"system": "http://hl7.org/fhir/sid/icd-10", "code": "I10", "display": "Essential (primary) hypertension"}]},
"onsetDateTime": "2026-03-02"
}'
clinicalStatus(active, resolved, in remission)和 verificationStatus(confirmed, provisional)是特意分开的:疑似诊断与已确认诊断不同,已解决的问题仍然是病史的一部分。
步骤 4:在一个事务中创建相关资源
当患者及其首次测量数据同时到达时(例如,来自诊所系统),请将它们作为 transaction Bundle 发送。要么全部存储,要么全部不存储。新资源之间的引用使用临时的 urn:uuid: ID,服务器会替换它们:
curl -X POST "$BASE" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" -d '{
"resourceType": "Bundle", "type": "transaction",
"entry": [
{"fullUrl": "urn:uuid:9f1c0d1e-0000-4000-8000-000000000001",
"resource": {"resourceType": "Patient", "name": [{"family": "Stan", "given": ["Mihai"]}], "gender": "male", "birthDate": "1990-02-01"},
"request": {"method": "POST", "url": "Patient"}},
{"resource": {"resourceType": "Observation", "status": "final",
"category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
"code": {"coding": [{"system": "http://loinc.org", "code": "29463-7", "display": "Body weight"}]},
"subject": {"reference": "urn:uuid:9f1c0d1e-0000-4000-8000-000000000001"},
"effectiveDateTime": "2026-10-10",
"valueQuantity": {"value": 82.4, "unit": "kg", "system": "http://unitsofmeasure.org", "code": "kg"}},
"request": {"method": "POST", "url": "Observation"}}
]
}'
transaction-response 每个资源有一个条目,包含 "status": "201 Created"、其 location 和已存储的资源。Observation 的 subject 现在指向真实的 Patient/fad3665a-…。
第 5 步:搜索
curl "$BASE/Observation?patient=$PID&code=http://loinc.org|85354-9&date=ge2026-10-01&_sort=-date" \
-H "Authorization: Bearer $KEY"
您将获得一个 searchset Bundle,其中包含 total 和匹配的资源,按最新排序。您经常会使用的其他搜索方式包括:Condition?patient=$PID&clinical-status=active、Observation?patient=$PID&category=laboratory 以及用于获取完整记录的 Patient/$PID/$everything。
步骤 6:在不丢失历史记录的情况下更新
高血压已解决。更改状态并添加结束日期,并使用 If-Match 和您读取的版本,这样您就不会覆盖其他人的更改:
curl -X PUT "$BASE/Condition/$CID" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
-H 'If-Match: W/"1"' -d '{ …the same Condition…, "clinicalStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "resolved"}]}, "abatementDateTime": "2026-10-11" }'
使用 200 OK 和 ETag: W/"2"。如果其他写入先于您到达,您将收到 412 并重新读取。早期版本仍然存在:
curl "$BASE/Condition/$CID/_history" -H "Authorization: Bearer $KEY"
返回两个版本:versionId 2 (resolved) 和 1 (active)。GET $BASE/Condition/$CID/_history/1 读取旧版本。记录中的任何内容都不会被静默覆盖。
步骤 7:查看谁编写了什么
每一次写入都会创建一个 Provenance 资源。对于血压读数:
curl "$BASE/Provenance?target=Observation/$OBS" -H "Authorization: Bearer $KEY"
{"resourceType": "Provenance",
"target": [{"reference": "Observation/d83d9075-…/_history/1"}],
"recorded": "2026-10-12T20:16:51.056000Z",
"activity": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/v3-DataOperation", "code": "CREATE"}]},
"agent": [{"type": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type", "code": "author"}]},
"who": {"identifier": {"system": "https://anpheros.com/fhir/CodeSystem/author-type", "value": "device"}, "display": "proj_…"},
"onBehalfOf": {"identifier": {"system": "https://anpheros.com/fhir/sid/organization", "value": "org_…"}, "display": "…"}}]}
您发送的作者类型 (device) 会与项目和组织一起记录。发送 X-Anpheros-Author-Ref: Practitioner/<id> 来命名写入背后的临床医生。
第 8 步:记录作为摘要
curl "$BASE/Patient/$PID/\$summary" -H "Authorization: Bearer $KEY"
返回一个国际患者摘要:一个 document Bundle,以一个 Composition 开头,并包含诸如“问题”、“药物”、“过敏症”和“生命体征”等部分,这些部分由上述资源构建而成。这就是要交给另一个系统或打印给医生的格式(FHIR 平台)。
偏好非 FHIR 的 JSON?
通过更简单的 REST 视图 /v1 也可以获得相同的数据,使用相同的 ID:POST /v1/patients/{id}/observations 获取 {"code": "85354-9", "category": "vital-signs", "effective_at": "…", "components": […]} 并存储相同的 FHIR Observation。根据您的代码选择使用哪种方式。请参阅 Medical data API 和 SDKs。
常见问题解答
存储病历的最佳方式是什么?
以编码、版本化的资源形式存储,并记录每个资源的作者。HL7 FHIR R4 提供了结构(Patient、Observation、Condition 等)、标准代码系统(如 LOINC 和 ICD-10)以及历史记录;FHIR 后端则在此基础上增加了搜索、同意和来源追溯功能。
使用 FHIR 是否需要 FHIR 服务器?
您需要一个能够存储和搜索 FHIR 资源并强制执行访问权限的地方。您可以自行运行开源 FHIR 服务器,或使用托管服务,例如 Anpheros;Anpheros 与其他 FHIR 服务器的比较 对各种选项进行了权衡,而 FHIR 与自定义医疗数据库 则讨论了构建自己的模式。
如何在 FHIR 中存储血压?
作为一条 Observation,使用 LOINC 代码 85354-9 和两个 component 条目:收缩压 8480-6 和舒张压 8462-4,每个条目都有一个 valueQuantity 单位 mm[Hg]。
我可以修改已存储的资源吗?
可以,通过 PUT 和 If-Match。每次更改都会创建一个新版本;早期版本仍可通过 _history 读取,并且 Provenance 记录会保存每次更改的作者。删除是软删除,会保留历史记录。
相关
- FHIR 平台:概念、资源类型和操作
- FHIR 代码系统:LOINC、ICD-10、ATC、UCUM
- 如何将实验室结果导入 FHIR 记录
- 医疗数据 API:相同数据的简化 REST 视图
- 免费 FHIR 数据库和沙盒
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card