iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0

前言

在上一篇文章中,我們正式認識了FHIR,並將Resource比喻成醫療資料中的標準化積木。

例如:

  • Patient代表病人的基本資料。
  • Encounter代表一次就醫事件。
  • Observation代表生命徵象或檢驗結果。
  • Condition代表疾病或診斷。
  • MedicationRequest代表用藥醫令。

但是,Resource不只是替資料分類而已。每一種Resource都有明確的用途、資料結構及欄位規則,而且不同Resource之間還可以互相連結。

今天要進一步了解FHIR Resource的設計概念、共同結構,以及一筆Resource通常包含哪些部分。


Resource是FHIR交換資料的基本單位

在一般的資訊系統中,病人的資料可能被放在不同資料表裡,例如:

  • 病人基本資料表
  • 掛號紀錄表
  • 診斷資料表
  • 檢驗結果表
  • 藥物處方表

每家醫院或系統廠商都可能使用不同的資料表名稱及欄位設計。

FHIR不會直接規定醫院內部一定要使用哪一種資料庫,而是針對「交換出去的資料」定義共同結構。

FHIR將醫療及行政概念拆分成不同Resource。例如,系統要交換病人基本資料時,可以使用Patient Resource;要交換檢驗結果時,則可以使用Observation Resource。

因此,Resource可以理解為:

FHIR用來表達及交換特定醫療概念的標準化資料單位。


為什麼要拆成不同Resource?

假設王小明到醫院看診,這次就醫可能產生以下資料:

  • 病人基本資料
  • 掛號及就醫紀錄
  • 血壓測量結果
  • 醫師診斷
  • 抽血檢驗結果
  • 藥物醫令
  • 檢查報告

如果把所有內容都放進同一份巨大資料中,可能出現幾個問題:

  • 每次只想查一項資料,卻要取得整份病歷。
  • 相同的病人基本資料可能被重複儲存。
  • 不同類型的資料混在一起,不容易管理。
  • 其中一個欄位變更時,可能要更新多個地方。
  • 系統很難只針對特定類型的資料進行搜尋。

FHIR將這些內容分成不同Resource:

醫療情境 對應Resource
王小明的基本資料 Patient
本次門診 Encounter
血壓及檢驗結果 Observation
醫師診斷 Condition
藥物醫令 MedicationRequest
檢查或檢驗報告 DiagnosticReport

每一種Resource負責自己的資料,再透過Reference互相連結。

這樣的設計稱為模組化。系統可以依照需求組合Resource,也能單獨查詢或更新特定資料。


Resource和資料庫資料表一樣嗎?

Resource看起來有點像資料庫中的資料表或一筆資料,但兩者並不完全相同。

資料庫是系統內部儲存資料的方法,每家醫院都可以依照自己的需求設計。FHIR Resource則是系統對外交換資料時使用的標準模型。

例如,某家醫院的病人資料可能分散在:

  • PatientBasicData
  • PatientContact
  • PatientAddress
  • MedicalRecordNumber

當系統要提供FHIR Patient資料時,可以先從這些資料表取得資料,再轉換成符合FHIR規範的Patient Resource。

反過來,系統收到Patient Resource後,也可以依照自己的資料庫設計,將不同欄位分別儲存。

所以:

FHIR規定資料交換時應該如何表達,但不強迫每套系統使用完全相同的內部資料庫。


一筆Patient Resource範例

以下是一份簡化的Patient Resource:

{
  "resourceType": "Patient",
  "id": "patient-001",
  "meta": {
    "versionId": "1",
    "lastUpdated": "2026-09-03T09:00:00Z"
  },
  "identifier": [
    {
      "system": "https://example.org/mrn",
      "value": "P001"
    }
  ],
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "王",
      "given": ["小明"]
    }
  ],
  "gender": "male",
  "birthDate": "2000-01-01"
}

接下來依序看看其中的重要欄位。


resourceType:這是哪一種Resource?

"resourceType": "Patient"

resourceType表示這筆資料所屬的Resource類型。

如果值是Patient,代表這是一筆病人基本資料;如果值是Observation,就表示這是一筆觀察或檢驗結果。

例如:

{
  "resourceType": "Observation"
}

FHIR Resource在JSON格式中必須讓接收方知道自己的類型,系統才能依照正確的結構解析後續欄位。

Resource類型的英文大小寫也需要注意。FHIR官方使用的是Patient,不能任意改成patientPATIENT


id:FHIR Server裡的Resource識別碼

"id": "patient-001"

id用來識別FHIR Server中的一筆Resource。

假設FHIR Server的基礎網址是:

https://example.org/fhir

Resource類型是Patient,id是patient-001,那麼這筆Resource的網址可能是:

https://example.org/fhir/Patient/patient-001

網址可以拆成:

FHIR Server網址 / Resource類型 / id

也就是:

https://example.org/fhir / Patient / patient-001

之後如果要使用API讀取這筆資料,就可以送出:

GET https://example.org/fhir/Patient/patient-001

id和identifier有什麼不同?

ididentifier是初學FHIR時很容易混淆的兩個欄位。

id

id是FHIR Server用來識別一筆Resource的邏輯ID。

"id": "patient-001"

它通常會出現在Resource的網址中:

/Patient/patient-001

identifier

identifier則是醫療或行政流程中用來識別某個對象的編號,例如:

  • 病歷號
  • 員工編號
  • 檢體編號
  • 醫令編號
  • 醫療機構代碼

範例如下:

"identifier": [
  {
    "system": "https://example.org/mrn",
    "value": "P001"
  }
]

其中:

  • system表示這個編號由哪一套識別系統定義。
  • value是實際的編號。

可以簡單整理成:

欄位 用途 範例
id 識別FHIR Server中的Resource patient-001
identifier 表示實務上的病歷號或其他業務編號 P001

同一個病人在不同FHIR Server中可能具有不同的id,但仍能帶有原本醫療機構使用的病歷號作為identifier

另外,真實環境中的identifier可能包含敏感資訊,不能將真實病歷號或身分識別資料任意放到公開測試伺服器。


meta:Resource的中繼資料

"meta": {
  "versionId": "1",
  "lastUpdated": "2026-09-03T09:00:00Z"
}

meta用來記錄與Resource管理有關的中繼資料。

常見內容包括:

  • versionId:Resource的版本
  • lastUpdated:最後更新時間
  • profile:這筆Resource宣告符合的Profile
  • tag:Resource的標籤
  • security:安全性相關標記

versionId

當Resource被更新時,FHIR Server可能會建立新的版本。

例如:

"versionId": "2"

表示目前看到的是第2個版本。不過,版本如何保存及能否查詢,仍取決於FHIR Server的實作方式。

lastUpdated

"lastUpdated": "2026-09-03T09:00:00Z"

表示這筆Resource最後更新的時間。

結尾的Z代表UTC時區。實際顯示時,可能需要依照使用者所在地轉換成當地時間。


active:這筆資料是否仍在使用?

"active": true

在Patient Resource中,active表示這筆病人紀錄是否仍被視為有效使用中的紀錄。

它是一個布林值:

  • true:有效
  • false:不再有效使用

需要注意的是,active: false並不代表病人死亡,也不一定代表資料被刪除。它只是表示這筆病人紀錄目前不再被積極使用。

不同Resource中的狀態欄位可能具有不同意義,不能只看到false就自行推測醫療狀況。


name:為什麼姓名是一個陣列?

Patient中的姓名可能寫成:

"name": [
  {
    "use": "official",
    "family": "王",
    "given": ["小明"]
  }
]

name外面使用中括號[],表示它是一個陣列,可以放入一個以上的姓名。

這是因為一個人可能同時具有:

  • 正式姓名
  • 曾用名
  • 別名
  • 綽號
  • 其他語言的姓名

use可以表示姓名的用途,family通常代表姓氏,given則表示名字。

FHIR需要考慮不同國家及文化的姓名結構,因此姓名不是單純的一個文字欄位,而是使用HumanName資料型別表達。


gender:FHIR中的性別代碼

"gender": "male"

FHIR R4中,Patient的gender欄位使用AdministrativeGender代碼,常見值包括:

代碼 意義
male 男性
female 女性
other 其他
unknown 未知

這個欄位名稱雖然是gender,但在FHIR規範中代表行政管理用途的性別分類,不能直接等同於所有臨床或個人性別相關資訊。

使用固定代碼的好處,是避免不同系統分別使用M1或其他方式表示相同概念。


birthDate:出生日期

"birthDate": "2000-01-01"

birthDate表示病人的出生日期,格式為:

YYYY-MM-DD

也就是:

年-月-日

使用統一格式可以避免不同地區對日期順序產生誤解。

FHIR的date資料型別也可能只記錄年份,或只記錄到年月,例如:

2000
2000-01

這可以用來表示來源資料只知道部分日期的情況,不應為了補齊格式而自行捏造不知道的日期。


每種Resource的欄位都一樣嗎?

不同Resource具有部分共同欄位,但主要內容會依照用途而不同。

Patient

可能包含:

  • identifier
  • active
  • name
  • telecom
  • gender
  • birthDate
  • address

Encounter

可能包含:

  • identifier
  • status
  • class
  • subject
  • participant
  • period
  • reasonCode

Observation

可能包含:

  • identifier
  • status
  • category
  • code
  • subject
  • effectiveDateTime
  • valueQuantity

例如,birthDate適合出現在Patient中,但不代表所有Resource都會有birthDate欄位。

使用FHIR時,不能自行把任何欄位放進任何Resource,而要查看該Resource的正式定義。


Resource如何互相連結?

FHIR透過Reference連結不同Resource。

假設有一筆Observation是王小明的體溫紀錄:

{
  "resourceType": "Observation",
  "id": "temperature-001",
  "status": "final",
  "code": {
    "text": "體溫"
  },
  "subject": {
    "reference": "Patient/patient-001",
    "display": "王小明"
  },
  "valueQuantity": {
    "value": 37.2,
    "unit": "°C"
  }
}

其中:

"subject": {
  "reference": "Patient/patient-001",
  "display": "王小明"
}

表示這筆Observation的對象,是id為patient-001的Patient。

reference是系統可以辨認的連結,而display則提供方便人類閱讀的文字。

真正建立資料關係的是:

"reference": "Patient/patient-001"

不能只依靠display中的「王小明」判斷病人,因為可能有其他病人也叫王小明。


Resource之間的關係

將前面的範例整理後,可以得到:

Patient/patient-001
王小明的基本資料
        │
        ├── Encounter/encounter-001
        │   王小明的一次門診
        │
        ├── Observation/temperature-001
        │   王小明的體溫
        │
        └── Condition/condition-001
            王小明的診斷

每一筆資料都是獨立Resource,但可以透過Reference連結。

這種方式能讓系統只取得需要的Resource。例如,只想查看體溫時,可以讀取Observation;需要病人姓名時,再依照Reference取得Patient。


Resource可以包含人類可閱讀的摘要

許多FHIR Resource屬於DomainResource,可以包含text欄位,提供人類可閱讀的摘要。

例如:

"text": {
  "status": "generated",
  "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">病人:王小明</div>"
}

其中:

  • status說明摘要內容如何產生。
  • div包含以XHTML表示的內容。

這個文字摘要可以協助人類閱讀Resource,但系統要進行搜尋、分析或交換時,仍應使用結構化欄位,不能只依靠摘要文字。


Extension是什麼?

FHIR需要適用於不同國家及醫療情境,因此可能出現標準Resource原本沒有定義的資料需求。

這時可以使用Extension進行擴充。

不過,Extension不是讓開發者隨意新增欄位。每個Extension都應該有明確的URL及定義,讓接收資料的系統知道它的意義。

簡化範例如下:

"extension": [
  {
    "url": "https://example.org/fhir/StructureDefinition/example-extension",
    "valueString": "範例資料"
  }
]

後續介紹TW Core IG及Profile時,會再進一步認識Extension的用途。


如何查看FHIR官方Resource定義?

FHIR R4官方網站提供Resource List,可以查看所有Resource。

進入特定Resource頁面後,通常可以看到:

  • Resource用途及範圍
  • 欄位結構
  • 欄位說明
  • 欄位資料型別
  • 欄位出現次數
  • 可以使用的代碼
  • JSON及XML範例
  • 支援的搜尋參數

例如,Patient Resource的官方頁面是:

https://hl7.org/fhir/R4/patient.html

Observation Resource的官方頁面是:

https://hl7.org/fhir/R4/observation.html

閱讀規範時要注意FHIR版本。本系列以R4為主,因此網址中會包含R4


FHIR的Resource只有一種固定寫法嗎?

FHIR對Resource的結構有明確規範,但不代表每一筆Patient都必須填入所有欄位。

有些欄位是選填,有些可以出現多次,實際要求還會受到Profile及使用情境影響。

例如,一筆Patient可能只有姓名:

{
  "resourceType": "Patient",
  "name": [
    {
      "text": "王小明"
    }
  ]
}

另一筆Patient可能同時包含姓名、生日、聯絡方式及地址。

所以判斷一份FHIR資料是否符合使用需求,不能只看它是否為合法JSON,還要確認:

  • 欄位是否存在於該Resource中
  • 資料型別是否正確
  • 必填欄位是否完整
  • 代碼是否符合規定
  • 是否符合指定的Profile

今日小結

今天更深入地認識了FHIR Resource。

Resource是FHIR表達及交換資料的基本單位,每種Resource負責特定的醫療或行政概念。不同Resource可以獨立存在,也可以透過Reference互相連結。

今天也釐清了幾個重要欄位:

  • resourceType:Resource類型
  • id:FHIR Server中的Resource識別碼
  • identifier:實務上的病歷號或其他業務編號
  • meta:版本、更新時間及Profile等中繼資料
  • text:提供人類閱讀的摘要
  • extension:表達標準Resource未涵蓋的額外需求

其中,我認為最重要的是不要把ididentifier混為一談,也不要把Resource直接當成醫院資料庫的資料表。

FHIR規範的是系統之間交換資料時的共同結構,醫院內部仍然可以依照自己的需求設計資料庫。

下一篇將實際打開一份Patient Resource,從最常見的病人基本資料開始,逐行看懂FHIR JSON。

明日預告

Day 8|第一次看FHIR Patient Resource

參考資料

  1. HL7 FHIR R4:Resource
    https://hl7.org/fhir/R4/resource.html

  2. HL7 FHIR R4:DomainResource
    https://hl7.org/fhir/R4/domainresource.html

  3. HL7 FHIR R4:Resource List
    https://hl7.org/fhir/R4/resourcelist.html

  4. HL7 FHIR R4:Patient
    https://hl7.org/fhir/R4/patient.html

  5. HL7 FHIR R4:References
    https://hl7.org/fhir/R4/references.html


上一篇
Day 6|FHIR是什麼?先從名稱開始認識
下一篇
Day 8|第一次看FHIR Patient Resource
系列文
《醫資生的 FHIR 30日入門:用 Postman 讀懂醫療資料交換》30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言