1. バンドルリソース
バンドル 多くのリソースを含むコンテナです。これは、FHIR が 1 つのリクエストで複数のリソースを処理し、ドキュメントをパッケージ化し、検索結果を返す方法です。
バンドルの種類
| 種類 | 説明 | ユースケース |
|---|---|---|
| サーチセット | 検索結果 | GET検索の応答 |
| 取引。トランザクション | アトミックオペレーショングループ | 多くの関連リソースを作成する |
| バッチ。バッチ | 運営独立グループ | 一括操作、各エントリは個別に処理されます |
| 文書。文書 | FHIR ドキュメント | 臨床文書 (組成物 + リソース) |
| メッセージ。メッセージ | FHIRメッセージ | メッセージング パラダイム (メッセージ ヘッダー + ペイロード) |
| コレクション | コレクション | 特定のインタラクションを行わずにリソースをプールする |
| 歴史。歴史 | 歴史の変遷 | _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"
}
}
]
}
使用例: 4 回の個別の呼び出しではなく、1 回の API 呼び出しですべての患者情報を取得します。
バッチ応答
{
"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\""
}
}
]
}
6. まとめ
バンドル — 多くのリソースを収納できるコンテナ、8 種類
トランザクション — アトミック、全か無か、内部参照には urn:uuid: を使用
バッチ — 独立した処理、並列、各エントリは独自のステータスを返します
取引に適しているのは、 データの整合性、バッチは次のような場合に適しています。 パフォーマンス。パフォーマンス