AnpherosAnpheros PlatformDevelopers

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"。三个细节对于可用的记录很重要:

实验室结果是相同的资源,包含 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 记录会保存每次更改的作者。删除是软删除,会保留历史记录。

相关

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card

Product updates by email

New features, guides and the end of the beta. One email a month at most.

Send me occasional Anpheros Platform updates by email (new features, API changes, guides). I'll confirm by email and can unsubscribe in one click from any email. Privacy