1. 捆綁資源
捆綁包 是一個包含許多資源的容器。這就是 FHIR 在一次請求中處理多個資源、打包文件並傳回搜尋結果的方式。
捆綁類型
| 類型 | 描述 | 使用案例 |
|---|---|---|
| 搜尋集 | 搜尋結果 | GET 搜尋的回應 |
| 交易。交易 | 原子操作組 | 創建許多相關資源 |
| 批次。批次 | 獨立營運組 | 批次操作,每個條目獨立處理 |
| 文檔。文件 | FHIR 文件 | 臨床文件(組成+資源) |
| 消息。留言 | FHIR訊息 | 訊息傳遞範例(MessageHeader + 有效負載) |
| 收藏 | 收藏 | 無需特定互動即可池化資源 |
| 歷史。歷史 | 歷史變遷 | _history的回應 |
| 訂閱通知 | 認購須知 | 即時通知 |
2. 交易捆綁
事務包處理 原子的 — 所有成功的條目或所有回滾。
例如:同時建立患者+遭遇+觀察
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"fullUrl": "urn:uuid:patient-temp-1",
"resource": {
"resourceType": "Patient",
"name": [
{
"family": "Nguyễn",
"given": ["Văn", "A"],
"text": "Nguyễn Văn A"
}
],
"gender": "male",
"birthDate": "1990-05-15",
"identifier": [
{
"system": "http://hospital.vn/mrn",
"value": "MRN-2025-001"
}
]
},
"request": {
"method": "POST",
"url": "Patient",
"ifNoneExist": "identifier=http://hospital.vn/mrn|MRN-2025-001"
}
},
{
"fullUrl": "urn:uuid:encounter-temp-1",
"resource": {
"resourceType": "Encounter",
"status": "in-progress",
"class": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "AMB"
}
]
}
],
"subject": {
"reference": "urn:uuid:patient-temp-1"
},
"period": {
"start": "2025-01-15T08:00:00+07:00"
}
},
"request": {
"method": "POST",
"url": "Encounter"
}
},
{
"fullUrl": "urn:uuid:obs-temp-1",
"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": "8310-5",
"display": "Body temperature"
}
]
},
"subject": {
"reference": "urn:uuid:patient-temp-1"
},
"encounter": {
"reference": "urn:uuid:encounter-temp-1"
},
"valueQuantity": {
"value": 37.2,
"unit": "°C",
"system": "http://unitsofmeasure.org",
"code": "Cel"
}
},
"request": {
"method": "POST",
"url": "Observation"
}
}
]
}
事務中的條件引用
使用 甕:uuid: 建立一個臨時 ID,以便同一交易中的條目相互引用。伺服器建立後會將其替換為實際的ID。
交易回應
{
"resourceType": "Bundle",
"type": "transaction-response",
"entry": [
{
"response": {
"status": "201 Created",
"location": "Patient/patient-001/_history/1",
"etag": "W/\"1\"",
"lastModified": "2025-01-15T08:00:00Z"
}
},
{
"response": {
"status": "201 Created",
"location": "Encounter/encounter-001/_history/1",
"etag": "W/\"1\""
}
},
{
"response": {
"status": "201 Created",
"location": "Observation/obs-001/_history/1",
"etag": "W/\"1\""
}
}
]
}
交易處理規則
- 伺服器依序處理:DELETE → POST → PUT/PATCH → GET(有條件)
- 所有條目必須成功 → 原子
- 如果任何輸入失敗 → 所有事務回滾
甕:uuid:在處理之前解析引用
3. 批量捆綁
批量處理 獨立的 — 每個條目單獨處理,失敗的條目不會影響其他條目。
{
"resourceType": "Bundle",
"type": "batch",
"entry": [
{
"request": {
"method": "GET",
"url": "Patient/patient-001"
}
},
{
"request": {
"method": "GET",
"url": "Observation?subject=Patient/patient-001&category=vital-signs&_sort=-date&_count=5"
}
},
{
"request": {
"method": "GET",
"url": "Condition?subject=Patient/patient-001&clinical-status=active"
}
},
{
"request": {
"method": "GET",
"url": "MedicationRequest?subject=Patient/patient-001&status=active"
}
}
]
}
使用案例:透過一次 API 呼叫(而不是 4 次單獨的呼叫)來獲取所有患者資訊。
大量響應
{
"resourceType": "Bundle",
"type": "batch-response",
"entry": [
{
"resource": {"resourceType": "Patient", "id": "patient-001", "...": "..."},
"response": {"status": "200 OK"}
},
{
"resource": {"resourceType": "Bundle", "type": "searchset", "...": "..."},
"response": {"status": "200 OK"}
},
{
"resource": {"resourceType": "Bundle", "type": "searchset", "...": "..."},
"response": {"status": "200 OK"}
},
{
"resource": {"resourceType": "OperationOutcome", "...": "..."},
"response": {"status": "404 Not Found"}
}
]
}
4. 比較事務與批量
| 特點 | 交易 | 批次 |
|---|---|---|
| 原子性 | ✅ 全有或全無 | ❌ 獨立 |
| 內部參考文獻 | ✅ urn:uuid: 已解決 | ❌ 不支持 |
| 故障處理 | 完全回滾 | 每個條目返回其自己的狀態 |
| 效能 | 較慢(事務邊界) | 更快(可以並行) |
| 使用案例 | 相關數據,需要一致性 | 批量讀取,獨立寫入 |
5、事務中的混合操作
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"request": {
"method": "PUT",
"url": "Patient/patient-001"
},
"resource": {"resourceType": "Patient", "id": "patient-001", "active": true}
},
{
"request": {
"method": "DELETE",
"url": "Observation/obs-old-001"
}
},
{
"request": {
"method": "POST",
"url": "Observation"
},
"resource": {"resourceType": "Observation", "status": "final"}
},
{
"request": {
"method": "GET",
"url": "Condition?subject=Patient/patient-001",
"ifNoneMatch": "W/\"5\""
}
}
]
}
六、總結
捆綁包 — 多種資源的容器,8 種不同類型
交易 — 原子性,全有或全無,使用 urn:uuid: 進行內部引用
批次 — 獨立處理,並行,每個條目返回自己的狀態
交易適合 資料完整性,批量適用於 性能。表現