Xem bản video
1. Bundle Resource
Bundle là container chứa nhiều Resources. Nó là cách FHIR xử lý nhiều resources trong một request, đóng gói documents, trả về kết quả search.
Bundle Types
| Type | Mô tả | Use case |
|---|---|---|
| searchset | Kết quả tìm kiếm | Response của GET search |
| transaction | Nhóm operations atomic | Tạo nhiều resources liên quan |
| batch | Nhóm operations independent | Bulk operations, mỗi entry xử lý độc lập |
| document | FHIR Document | Clinical document (Composition + resources) |
| message | FHIR Message | Messaging paradigm (MessageHeader + payload) |
| collection | Bộ sưu tập | Gom resources không có interaction cụ thể |
| history | Lịch sử thay đổi | Response của _history |
| subscription-notification | Thông báo subscription | Real-time notifications |
2. Transaction Bundle
Transaction Bundle xử lý atomic — tất cả entries thành công hoặc tất cả rollback.
Ví dụ: Tạo Patient + Encounter + Observation cùng lúc
{
"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"
}
}
]
}
Conditional References trong Transaction
Sử dụng urn:uuid: làm temporary ID để các entries trong cùng transaction reference nhau. Server sẽ thay thế bằng ID thực tế sau khi tạo.
Transaction Response
{
"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\""
}
}
]
}
Transaction Processing Rules
- Server xử lý theo thứ tự: DELETE → POST → PUT/PATCH → GET (conditional)
- Tất cả entries phải thành công → atomic
- Nếu bất kỳ entry nào fail → toàn bộ transaction rollback
urn:uuid:references được resolve trước khi xử lý
3. Batch Bundle
Batch xử lý independent — mỗi entry xử lý riêng, một entry fail không ảnh hưởng entries khác.
{
"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"
}
}
]
}
Use case: Lấy tất cả thông tin bệnh nhân trong một API call thay vì 4 calls riêng biệt.
Batch Response
{
"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. So sánh Transaction vs Batch
| Đặc tính | Transaction | Batch |
|---|---|---|
| Atomicity | ✅ All-or-nothing | ❌ Independent |
| Internal references | ✅ urn:uuid: resolved | ❌ Không hỗ trợ |
| Failure handling | Toàn bộ rollback | Mỗi entry trả status riêng |
| Performance | Chậm hơn (transaction boundary) | Nhanh hơn (parallel possible) |
| Use case | Data liên quan, cần consistency | Batch read, independent writes |
5. Mixed Operations trong Transaction
{
"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\""
}
}
]
}
6. Tổng kết
Bundle — Container cho nhiều resources, 8 types khác nhau
Transaction — Atomic, all-or-nothing, dùng urn:uuid: cho internal references
Batch — Independent processing, parallel, mỗi entry trả status riêng
Transaction phù hợp cho data integrity, Batch phù hợp cho performance