在前兩篇文章中,我們認識了REST API,以及GET、POST、PUT、DELETE等常見HTTP方法。
了解基本概念後,接下來要認識一套經常用於API開發及測試的工具——Postman。
Postman可以協助使用者建立HTTP Request、設定Headers及查看Server回傳的Response。即使沒有撰寫程式,也能透過圖形化介面觀察一次API溝通的完整過程。
今天不進行實際操作,而是透過一個FHIR API Request範例,了解Postman可以協助我們查看哪些資訊。
Postman是一套API開發及測試工具。
當開發人員需要確認一個API能否正常運作時,可以利用Postman建立並送出Request,再查看Server回傳的結果。
Postman可以協助處理:
如果不使用Postman,也可以利用瀏覽器、程式碼或命令列工具呼叫API。Postman的特色是將這些內容整理在圖形化介面中,讓Request與Response的結構更容易觀察。
在Day 13中,我們曾經將API比喻成餐廳點餐。
Postman在這個情境中扮演Client,也就是提出要求的一方。
整個過程可以簡化成:
Postman建立Request
↓
Request傳送到FHIR Server
↓
FHIR Server處理要求
↓
FHIR Server建立Response
↓
Postman顯示Response
Postman本身不是FHIR Server,也不會自動產生病人的醫療資料。
它比較像是一個方便使用者建立及觀察API Request的工具。
假設Client想搜尋FHIR Server中的Patient,可以建立以下Request:
GET https://hospital.example.org/fhir/Patient?name=王小明
Accept: application/fhir+json
這個Request可以拆成幾個部分:
| 部分 | 範例 | 用途 |
|---|---|---|
| HTTP方法 | GET |
表示讀取或搜尋資料 |
| Base URL | https://hospital.example.org/fhir |
FHIR Server的位置 |
| Resource類型 | Patient |
表示要搜尋Patient |
| 搜尋參數 | name=王小明 |
指定搜尋條件 |
| Request Header | Accept: application/fhir+json |
希望收到FHIR JSON |
Postman會將這些內容組合成HTTP Request,再傳送給FHIR Server。
Postman可以選擇不同的HTTP方法,例如:
在FHIR中,不同方法通常代表不同操作。
| HTTP方法 | FHIR常見用途 |
|---|---|
| GET | 讀取或搜尋Resource |
| POST | 建立新的Resource |
| PUT | 更新指定Resource |
| DELETE | 刪除指定Resource |
| PATCH | 修改Resource的部分內容 |
例如:
GET /Patient/patient-001
表示讀取一筆Patient。
POST /Patient
表示要求Server建立新的Patient。
Postman只是協助Client送出指定方法,實際上是否允許該操作,仍然由FHIR Server的設定、權限及CapabilityStatement決定。
URL表示Request要送往哪個位置。
例如:
https://hospital.example.org/fhir/Patient/patient-001
可以拆成:
| 部分 | 內容 |
|---|---|
| 通訊協定 | https |
| Server網域 | hospital.example.org |
| FHIR基礎路徑 | /fhir |
| Resource類型 | /Patient |
| Resource id | /patient-001 |
其中:
https://hospital.example.org/fhir
是FHIR Server的Base URL。
Patient/patient-001
則指出要讀取的Resource類型及id。
URL如果缺少路徑、拼字錯誤或Resource名稱大小寫不正確,就可能無法取得預期結果。
如果不知道Resource id,也可以使用搜尋參數尋找資料。
例如:
GET /Patient?name=王小明
其中:
?name=王小明
表示依照姓名搜尋Patient。
如果加入多個條件,可以使用&連接:
GET /Patient?name=王小明&birthdate=2000-01-01
這表示同時使用姓名及出生日期作為搜尋條件。
不過,FHIR Server不一定支援所有搜尋參數。實際可以使用哪些參數,需要查看Resource規範及Server的CapabilityStatement。
Headers用來提供與Request有關的附加資訊。
例如:
Accept: application/fhir+json
表示Client希望收到FHIR JSON格式的Response。
如果Client傳送的Request Body是FHIR JSON,可能使用:
Content-Type: application/fhir+json
兩者的差異是:
| Header | 用途 |
|---|---|
Accept |
說明Client希望收到的格式 |
Content-Type |
說明Client目前送出的內容格式 |
API也可能使用Header傳送身分驗證資訊,例如:
Authorization: Bearer <access-token>
Access Token屬於敏感資訊,不應出現在公開文章、截圖或程式碼中。
GET通常用於讀取或搜尋資料,因此一般不需要Request Body。
POST及PUT則經常需要透過Body傳送FHIR Resource。
例如,建立Patient時,Request Body可能包含:
{
"resourceType": "Patient",
"active": true,
"name": [
{
"text": "王小明"
}
]
}
Request Body必須符合:
JSON語法正確,不代表一定符合FHIR規範。
FHIR Server收到Request後,可能進行:
Response通常包含:
Postman會將這些內容顯示出來,協助使用者判斷Request是否成功。
Status Code是由三位數字組成的HTTP狀態碼。
常見狀態碼包括:
| Status Code | 常見意義 |
|---|---|
| 200 OK | Request成功 |
| 201 Created | Resource建立成功 |
| 204 No Content | Request成功,但沒有Response Body |
| 400 Bad Request | Request格式或內容有問題 |
| 401 Unauthorized | 尚未完成有效的身分驗證 |
| 403 Forbidden | 身分已確認,但沒有操作權限 |
| 404 Not Found | 找不到指定Resource |
| 405 Method Not Allowed | Server不允許使用該HTTP方法 |
| 422 Unprocessable Entity | Resource內容無法通過處理或驗證 |
| 500 Internal Server Error | Server內部發生錯誤 |
查看Response時,不能只看Body是否出現資料,也要一起確認Status Code。
Response Headers用來描述Server回傳內容的格式及其他資訊。
例如:
Content-Type: application/fhir+json
表示Response Body是FHIR JSON。
如果Server成功建立Resource,也可能在Header中提供Resource的位置,例如:
Location: https://hospital.example.org/fhir/Patient/123/_history/1
這表示新Resource的id是123,目前版本是1。
不同FHIR Server實際回傳的Headers可能有所不同。
如果Client讀取一筆Patient成功,Response Body可能是Patient Resource:
{
"resourceType": "Patient",
"id": "patient-001",
"active": true,
"name": [
{
"text": "王小明"
}
]
}
如果Client進行搜尋,Response Body通常是Bundle:
{
"resourceType": "Bundle",
"type": "searchset",
"total": 1,
"entry": [
{
"resource": {
"resourceType": "Patient",
"id": "patient-001",
"name": [
{
"text": "王小明"
}
]
}
}
]
}
搜尋結果中的Patient會放在:
entry → resource
所以看到最外層的resourceType是Bundle時,不代表Server回傳錯誤,而是使用Bundle包裝搜尋結果。
Request:
GET /Patient/patient-001
Response最外層通常是:
{
"resourceType": "Patient"
}
Request:
GET /Patient?name=王小明
Response最外層通常是:
{
"resourceType": "Bundle",
"type": "searchset"
}
可以整理成:
| 操作 | Request | Response |
|---|---|---|
| Read | GET /Patient/123 |
Patient |
| Search | GET /Patient?name=王小明 |
Bundle |
兩者都使用GET,但URL及Response結構不同。
如果Request發生問題,FHIR Server可能回傳OperationOutcome。
例如:
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "invalid",
"diagnostics": "The resource could not be processed."
}
]
}
OperationOutcome常見欄位包括:
| 欄位 | 用途 |
|---|---|
severity |
問題嚴重程度 |
code |
問題類型 |
details |
問題說明 |
diagnostics |
技術或診斷資訊 |
expression |
發生問題的欄位位置 |
因此,遇到錯誤時可以按照以下順序閱讀:
resourceType
issue
severity
code
diagnostics或details
Postman不是FHIR專用工具,也不會自動判斷一份資料是否完全符合FHIR規範。
它主要負責:
FHIR Server則負責:
可以整理成:
| Postman | FHIR Server |
|---|---|
| 扮演Client | 扮演Server |
| 建立及送出Request | 接收及處理Request |
| 顯示Response | 建立Response |
| 不負責保存正式病歷 | 依系統設計管理FHIR資料 |
| 不代表Resource一定正確 | 依規則驗證及處理Resource |
學習FHIR時,可能會看到公開測試伺服器,例如HAPI FHIR Test Server。
它的FHIR R4 Base URL是:
https://hapi.fhir.org/baseR4
公開測試Server的用途主要是展示及測試FHIR功能。
它與正式醫療系統有幾項重要差異:
| 公開測試Server | 正式醫療Server |
|---|---|
| 提供學習或測試用途 | 支援正式醫療服務 |
| 資料可能隨時被修改或清除 | 需要依制度保存資料 |
| 可能允許匿名存取部分功能 | 通常需要身分驗證及權限 |
| 可能由不同使用者共用 | 有明確的組織及管理責任 |
| 不可放入真實病人資料 | 依法律及安全規範處理病歷 |
即使測試Server公開,也不代表可以將真實病人姓名、病歷號、電話、地址或檢驗結果放入其中。
Postman可以替我們組合及傳送Request,卻不會代替使用者理解資料。
如果只知道按下Send,卻不知道Request中的每一部分代表什麼,就很難判斷錯誤原因。
例如,Request失敗時,需要分辨:
所以Postman是一套輔助工具,真正重要的仍然是對HTTP、REST API及FHIR規範的理解。
以讀取Patient為例:
GET https://hospital.example.org/fhir/Patient/patient-001
Accept: application/fhir+json
FHIR Server會:
patient-001
200 OK
Content-Type: application/fhir+json
{
"resourceType": "Patient",
"id": "patient-001"
}
404 Not Found
Content-Type: application/fhir+json
Response Body可能是OperationOutcome。
整個過程可以整理成:
HTTP方法+URL+Headers+Body
↓
Request
↓
FHIR Server
↓
Response
↓
Status Code+Headers+FHIR Resource
今天認識了Postman在API溝通中的角色。
Postman是一套協助建立Request及查看Response的工具,在FHIR情境中扮演Client。
一個Request可能包含:
Server處理後的Response則可能包含:
我認為今天最重要的觀念是:
Postman只是協助傳送及觀察API資料,FHIR Resource的結構、代碼、權限與處理規則仍然由FHIR規範及Server決定。
下一篇將認識FHIR Server的自我介紹——CapabilityStatement,看看一台Server如何說明自己的FHIR版本、支援的Resource及API功能。
Day 16|用metadata認識一台FHIR Server
Postman官方網站
https://www.postman.com/
Postman官方文件:Quick Start
https://learning.postman.com/docs/getting-started/quick-start/
HL7 FHIR R4:RESTful API
https://hl7.org/fhir/R4/http.html
HL7 FHIR R4:Search
https://hl7.org/fhir/R4/search.html
HL7 FHIR R4:Bundle
https://hl7.org/fhir/R4/bundle.html
HL7 FHIR R4:OperationOutcome
https://hl7.org/fhir/R4/operationoutcome.html