在上一篇文章中,我們認識了Postman以及一個FHIR API Request可能包含的內容。
不過,就算知道FHIR Server的網址,也不能直接假設它一定支援所有Resource、搜尋參數及HTTP方法。
例如,有些FHIR Server可能:
在正式與FHIR Server溝通前,Client需要先了解Server能夠提供哪些功能。
FHIR使用CapabilityStatement描述這些資訊,而RESTful FHIR Server通常會透過metadata端點提供自己的CapabilityStatement。
今天不進行任何實際操作,而是從概念及範例了解metadata與CapabilityStatement。
在FHIR RESTful API中,可以使用以下形式取得Server的能力資訊:
GET [base]/metadata
其中:
[base]
代表FHIR Server的Base URL。
假設一台虛構FHIR Server的Base URL是:
https://hospital.example.org/fhir
那麼它的metadata位置就是:
https://hospital.example.org/fhir/metadata
這個Request的意思不是查詢病人或檢驗結果,而是詢問FHIR Server:
你使用哪個FHIR版本?支援哪些Resource及API功能?
Server通常會回傳一筆CapabilityStatement Resource。
CapabilityStatement可以理解成FHIR Server的「能力說明書」。
它可能描述:
因此,Client不應該只知道對方是FHIR Server,就直接假設所有功能都可以使用。
應該先查看CapabilityStatement,再依照Server實際宣告的能力建立Request。
CapabilityStatement不是一份與FHIR無關的說明文字,它本身也是FHIR Resource。
一份經過簡化的CapabilityStatement可能如下:
{
"resourceType": "CapabilityStatement",
"id": "example-capability",
"status": "active",
"date": "2026-09-03",
"kind": "instance",
"software": {
"name": "Example FHIR Server",
"version": "1.0.0"
},
"implementation": {
"description": "範例醫院FHIR Server",
"url": "https://hospital.example.org/fhir"
},
"fhirVersion": "4.0.1",
"format": [
"json",
"xml"
]
}
最外層可以看到:
"resourceType": "CapabilityStatement"
表示這是一筆CapabilityStatement Resource。
它和Patient、Observation一樣,都遵循FHIR Resource的基本結構,只是用途不同。
"status": "active"
status表示這份CapabilityStatement目前的發布狀態。
可能使用的代碼包括:
| 代碼 | 基本意義 |
|---|---|
draft |
草稿 |
active |
正式使用中 |
retired |
已停止使用 |
unknown |
狀態未知 |
如果值是:
active
表示這份CapabilityStatement目前處於有效使用狀態。
這個status描述的是CapabilityStatement文件本身,不是FHIR Server當下有沒有在線,也不是病人的醫療狀態。
"kind": "instance"
kind說明這份CapabilityStatement的用途。
FHIR R4常見的值包括:
| 代碼 | 基本意義 |
|---|---|
instance |
描述某一個實際運作的系統 |
capability |
描述系統可能提供的能力 |
requirements |
描述某個使用情境所需要的能力 |
從特定FHIR Server的metadata取得的CapabilityStatement,通常會使用:
"kind": "instance"
因為它描述的是目前這台實際Server的能力。
"software": {
"name": "Example FHIR Server",
"version": "1.0.0"
}
software可以說明提供FHIR服務的軟體資訊。
常見欄位包括:
name:軟體名稱version:軟體版本releaseDate:發布日期軟體版本和FHIR版本是不同概念。
例如:
1.0.0
4.0.1
不能因為軟體版本中出現數字4,就認為它一定使用FHIR R4。
"implementation": {
"description": "範例醫院FHIR Server",
"url": "https://hospital.example.org/fhir"
}
implementation描述這項實際FHIR服務。
常見欄位包括:
| 欄位 | 用途 |
|---|---|
description |
服務說明 |
url |
FHIR服務的Base URL |
custodian |
維護或管理服務的機構 |
其中:
"url": "https://hospital.example.org/fhir"
表示這台FHIR Server提供服務的基本位置。
"fhirVersion": "4.0.1"
fhirVersion是CapabilityStatement中非常重要的欄位。
常見FHIR版本包括:
FHIR R4的版本號是:
4.0.1
不同FHIR版本的Resource、欄位、代碼及規則可能不同,所以Client需要確認Server使用的版本是否符合自己的需求。
本系列以FHIR R4為主,因此看到:
"fhirVersion": "4.0.1"
就表示Server使用的版本與本系列相符。
"format": [
"json",
"xml"
]
format表示Server支援哪些FHIR資料格式。
常見格式包括:
因為format是一個Array,所以Server可以同時宣告支援多種格式。
有些CapabilityStatement可能使用較完整的MIME Type,例如:
"format": [
"application/fhir+json",
"application/fhir+xml"
]
如果Client希望收到FHIR JSON,可以透過HTTP Header表示:
Accept: application/fhir+json
但Server實際支援哪些格式,仍然應以CapabilityStatement為準。
CapabilityStatement中的rest欄位,用來描述FHIR RESTful API相關能力。
簡化範例如下:
"rest": [
{
"mode": "server",
"resource": [
{
"type": "Patient"
},
{
"type": "Observation"
}
]
}
]
其中:
"mode": "server"
表示這份內容描述Server端提供的FHIR RESTful能力。
如果是:
"mode": "client"
則表示描述某個Client預期使用或支援的能力。
在rest.resource中,可以找到Server支援的Resource類型。
例如:
"resource": [
{
"type": "Patient"
},
{
"type": "Observation"
},
{
"type": "Encounter"
}
]
這表示Server宣告支援:
如果清單中沒有MedicationRequest,可能代表Server沒有宣告提供MedicationRequest的RESTful服務。
不過,CapabilityStatement可能很長,實際閱讀時要確認自己查看的是正確的rest區段及Server模式。
Server支援Patient,不代表Patient的所有操作都能使用。
CapabilityStatement會透過interaction說明每種Resource支援哪些互動。
例如:
{
"type": "Patient",
"interaction": [
{
"code": "read"
},
{
"code": "search-type"
},
{
"code": "create"
},
{
"code": "update"
}
]
}
可能的互動包括:
| interaction code | 意義 |
|---|---|
read |
讀取一筆Resource |
vread |
讀取特定歷史版本 |
search-type |
搜尋特定類型Resource |
create |
建立Resource |
update |
更新Resource |
patch |
修改部分內容 |
delete |
刪除Resource |
history-instance |
查看單一Resource歷史紀錄 |
history-type |
查看某類Resource歷史紀錄 |
上面的範例表示Patient支援:
但沒有宣告delete,所以不能直接假設Client可以刪除Patient。
假設CapabilityStatement中寫著:
"resource": [
{
"type": "Patient",
"interaction": [
{
"code": "read"
},
{
"code": "search-type"
}
]
},
{
"type": "Observation",
"interaction": [
{
"code": "read"
}
]
}
]
這表示:
| Resource | read | search-type |
|---|---|---|
| Patient | 支援 | 支援 |
| Observation | 支援 | 未宣告支援 |
即使Patient和Observation都存在於同一台FHIR Server,它們允許的操作仍然可能不同。
所以判斷Server能力時,不能只查看Resource名稱,也要查看該Resource底下的interaction。
CapabilityStatement也能列出Resource支援的搜尋參數。
例如:
{
"type": "Patient",
"searchParam": [
{
"name": "name",
"definition": "http://hl7.org/fhir/SearchParameter/Patient-name",
"type": "string"
},
{
"name": "birthdate",
"definition": "http://hl7.org/fhir/SearchParameter/individual-birthdate",
"type": "date"
},
{
"name": "identifier",
"definition": "http://hl7.org/fhir/SearchParameter/Patient-identifier",
"type": "token"
}
]
}
這表示Server宣告支援以下Patient搜尋參數:
name
birthdate
identifier
搜尋URL的概念可能是:
GET /Patient?name=王小明
GET /Patient?birthdate=2000-01-01
GET /Patient?identifier=MRN0001
不同搜尋參數具有不同型別,例如:
| SearchParameter type | 常見用途 |
|---|---|
string |
姓名或一般文字 |
date |
日期 |
token |
代碼或Identifier |
reference |
Resource Reference |
number |
數值 |
quantity |
數值及單位 |
uri |
URI |
composite |
多個條件組合 |
搜尋參數名稱看起來合理,不代表Server一定支援,仍要查看CapabilityStatement。
FHIR基礎規範保留一定彈性,實際使用時可能透過Profile限制Resource。
CapabilityStatement中的Resource可以宣告支援的Profile,例如:
{
"type": "Patient",
"profile": "https://example.org/fhir/StructureDefinition/example-patient"
}
這表示Server處理Patient時,可能要求或宣告符合指定的Patient Profile。
另外,也可能透過supportedProfile列出其他支援的Profile。
Profile可能規定:
因此,知道Server支援Patient仍然不夠,還要確認它支援或要求哪一個Patient Profile。
CapabilityStatement可以在rest.security中描述安全相關資訊。
簡化範例如下:
"security": {
"cors": true,
"service": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/restful-security-service",
"code": "SMART-on-FHIR",
"display": "SMART-on-FHIR"
}
]
}
],
"description": "使用SMART on FHIR進行授權"
}
它可能說明:
不過,CapabilityStatement不會因為列出安全服務,就自動提供帳號或Access Token。
Client仍然需要依照該系統的授權流程取得合法權限。
除了各Resource自己的interaction,CapabilityStatement也可以列出系統層級的互動。
例如:
"interaction": [
{
"code": "transaction"
},
{
"code": "batch"
},
{
"code": "search-system"
}
]
可能的用途包括:
| code | 基本意義 |
|---|---|
transaction |
將多個操作當成一組交易處理 |
batch |
一次送出多個彼此獨立的操作 |
search-system |
跨Resource類型搜尋 |
history-system |
查看Server層級歷史紀錄 |
這裡的interaction和特定Resource下的interaction位置不同。
rest.resource.interaction描述某一種Resource的能力。rest.interaction描述整個系統層級的能力。FHIR除了read、create及update等標準互動,也可以定義Operation。
Operation的名稱通常會以$開頭,例如:
$validate
$everything
CapabilityStatement可以透過operation列出Server支援的Operation。
簡化範例如下:
"operation": [
{
"name": "validate",
"definition": "http://hl7.org/fhir/OperationDefinition/Resource-validate"
}
]
這表示Server宣告支援$validate,可以用來檢查Resource是否符合相關規則。
不是所有FHIR Server都支援相同Operation,使用前仍要查看CapabilityStatement及該Server文件。
一份完整的CapabilityStatement可能非常長,可以先依照以下層次閱讀:
CapabilityStatement
├── 基本資料
│ ├── status
│ ├── date
│ └── kind
│
├── Server資訊
│ ├── software
│ └── implementation
│
├── FHIR規格
│ ├── fhirVersion
│ └── format
│
└── RESTful能力
└── rest
├── mode
├── security
├── resource
│ ├── type
│ ├── profile
│ ├── interaction
│ └── searchParam
├── interaction
└── operation
第一次看到時,不需要理解所有欄位,可以先找:
resourceType
status
kind
fhirVersion
format
rest.mode
rest.resource.type
interaction.code
searchParam.name
以下CapabilityStatement宣告Server使用FHIR R4、支援JSON與XML,也提供Patient的read及search-type。
{
"resourceType": "CapabilityStatement",
"id": "example-capability",
"status": "active",
"date": "2026-09-03",
"kind": "instance",
"software": {
"name": "Example FHIR Server",
"version": "1.0.0"
},
"implementation": {
"description": "範例醫院FHIR服務",
"url": "https://hospital.example.org/fhir"
},
"fhirVersion": "4.0.1",
"format": [
"application/fhir+json",
"application/fhir+xml"
],
"rest": [
{
"mode": "server",
"resource": [
{
"type": "Patient",
"interaction": [
{
"code": "read"
},
{
"code": "search-type"
}
],
"searchParam": [
{
"name": "name",
"type": "string"
},
{
"name": "birthdate",
"type": "date"
}
]
}
]
}
]
}
從這份資料可以解讀出:
| 問題 | 答案 |
|---|---|
| 這是什麼Resource? | CapabilityStatement |
| 是否為有效狀態? | 是,status為active |
| 描述實際Server嗎? | 是,kind為instance |
| 使用哪個FHIR版本? | FHIR R4 4.0.1 |
| 支援哪些格式? | FHIR JSON及XML |
| 支援哪個Resource? | Patient |
| Patient可以讀取嗎? | 可以,支援read |
| Patient可以搜尋嗎? | 可以,支援search-type |
| 支援哪些搜尋參數? | name及birthdate |
| 有宣告可以刪除Patient嗎? | 沒有看到delete |
原則上,Client應依照CapabilityStatement宣告的內容判斷Server能力。
如果CapabilityStatement沒有列出某項Resource或互動,就不應直接假設它可以使用。
但實務上仍可能遇到:
因此,CapabilityStatement是重要依據,但正式系統整合時仍需要搭配:
這兩個名詞容易混淆。
主要回答:
這個系統支援哪些FHIR功能?
例如:
主要回答:
在特定國家、組織或使用情境中,FHIR應該如何使用?
例如:
可以簡單整理:
| 項目 | 主要用途 |
|---|---|
| CapabilityStatement | 描述系統能力 |
| Implementation Guide | 定義特定情境的實作規則 |
一台Server可能透過CapabilityStatement宣告支援某個Implementation Guide中的Profile。
如果沒有先了解Server能力,Client可能直接提出Server無法處理的Request。
例如:
CapabilityStatement能讓Client在建立Request前,先了解Server提供的功能及限制。
可以將metadata想成餐廳的菜單與服務說明:
顧客先看菜單,才能依照餐廳真正提供的服務點餐。
今天認識了FHIR Server的能力說明方式。
FHIR RESTful Server通常會透過:
GET [base]/metadata
提供CapabilityStatement。
CapabilityStatement可以說明:
我認為今天最重要的觀念是:
知道對方是FHIR Server,不代表它支援FHIR規範中的所有功能。
Client應先了解CapabilityStatement,再依照Server真正宣告的能力設計資料交換方式。
下一篇將介紹FHIR的read互動,看看系統知道Resource類型及id後,如何表示「讀取一筆Patient」,以及成功與失敗時可能收到什麼Response。
Day 17|第一次用API讀取Patient資料
HL7 FHIR R4:CapabilityStatement
https://hl7.org/fhir/R4/capabilitystatement.html
HL7 FHIR R4:RESTful API-Capabilities
https://hl7.org/fhir/R4/http.html#capabilities
HL7 FHIR R4:Search
https://hl7.org/fhir/R4/search.html
HL7 FHIR R4:Operations
https://hl7.org/fhir/R4/operations.html
HL7 FHIR R4:Profiling FHIR
https://hl7.org/fhir/R4/profiling.html