V.FHIR Server
13 HAPI FHIR 操作說明 CRUD與Swagger,POSTMan與HAPI FHIR互動的方式
其實我尋思,這個內容似乎可以與昨天的內容合併成一節,但這樣內容又會稍多了。
今天要談的是HAPI FHIR安裝完畢後要怎麼使用它,首先是Swagger UI,HAPI FHIR在建立時即已內建Swagger UI可用
http://localhost:8080/fhir/swagger-ui/
Swagger UI是OpenAPI的實作,使用者可以一目了然關於所有API的操作內容與輸入參數
在HAPI FHIR中,讀者可以透過Swagger-UI來找尋每個Resource對應的操作方式,也可以直接使用API條目來測試使用,
由於FHIR Server的內容是由Resource組成,在執行操作後,除了會返回Resource本身的操作外,FHIR Server會回覆需求端OperationOutcome的Resource,
在正式開始之前,請先確定你的Docker與HAPI FHIR都是正常開啟的狀態,
舉例:拿twci的Patient Resource 範例來測試HAPI FHIR 的$validate驗證功能
POST | http://localhost:8080/fhir/Patient/$validate?_profile=http:/localhost:8080/fhir/StructureDefinition/Patient-twci
在這個Resource中,HAPI FHIR告訴我們根據Patient TWCI Profile的驗證,
這個Resource有1個Error,3個Warning,可以很概觀的看到HAPI FHIR回報的問題都是找不到用來驗證的資源,所以返回問題
從最簡單的CRUD開始吧,首先先來找一個示範用的Patient Resource,在這裡我會同時使用Postman與HAPI FHIR的GUI來操作,
可以先複製下面的Patient資源,或自己有一個可以拿來上傳測試的版本都可以。
{
"resourceType": "Patient",
"id": "pat-example",
"active": true,
"name": [ {
"use": "official",
"family": "Doe",
"given": [ "John" ]
} ]
}
在Postman中,輸入:
POST | http://localhost:8080/fhir/Patient
調到Body選項,使用raw並選擇JSON格式,將Patient的JSON貼上去後按下Send,
下方會回傳Response Body,這是一個範例:
{
"resourceType": "Patient",
"id": "152442",
"meta": {
"versionId": "1",
"lastUpdated": "2025-08-12T06:24:55.503+00:00",
"source": "#kikvTGdSK7iRCkEQ"
},
"active": true,
"name": [
{
"use": "official",
"family": "Doe",
"given": [
"John"
]
}
]
}
可以看到原來的Patient JSON檔被加上了meta,並且id變成了流水號,
在FHIR Server上,使用POST(Create)一筆Resource,FHIR Server會自動分配id給這筆Resource,
問題來了,既然id會被FHIR Server無情改造,但我又想要有一組我能識別的id,該怎麼辦
這時候請改用PUT,
PUT | http://localhost:8080/fhir/Patient/pat-example
原來的Resource ID就會被保留下來,不會變成流水號。
在HAPI FHIR的介面上也是如此操作,以Patient為例子,
HAPI FHIR的左側Resources中找到Patient的欄位,將中間的欄位從Search調到CRUD Operations,
CRUD對應到的分別是POST/GET/PUT/DELETE,按照直覺性的去使用測試看看即可,
要特別說的地方是,當我們點入Resource分頁時,中間頁面可以看到預設是Search,在這裡可以使用前幾天談到的Search.html內的內容,
Search其實對應到的是GET方法,唯一不同的地方是,
若Search(GET)找到符合的Resource為多筆時,FHIR Server會返回Bundle/searchSet而不是個別的Resource,
基本的CRUD很簡單,在swagger-ui內,還可以看到一些比較進階的操作,詳細的使用方法在HAPI FHIR的Document內可以看到
https://hapifhir.io/hapi-fhir/docs/server_jpa/introduction.html
2. HAPI FHIR的補充
用Docker來布置HAPI FHIR固然方便,但是容器的特性會讓修改設定或匯入資源變得困難,
筆者在這裡踩了非常多的坑,總結出了一些方法來處理,
首先是匯入IG,在上面的OperationOutcome Resource中我們可以看到HAPI FHIR驗證資料失敗的原因是
HAPI FHIR找不到在他資料庫中的這些StructureDefinition, CodeSystem等Resource,因此無法進行驗證,
也就是說,要進行驗證必須要將IG、CodeSystem等Resource全部都上傳上去,
前面在談Bundle的功能的時候,有提到Bundle中有個Type叫做Batch,他可以一次性的上傳多筆資源,只是需要開啟Bulk Data的設定,
而無論是調整設定、匯入Resource,在正常HAPI FHIR的操作裡都應該從yaml內撰寫設定,
這邊先推薦大家記錄起來Chinlin的hackmd,Chinlin是Burni FHIR Server的開發者之一,對HAPI FHIR有較深的理解
https://hackmd.io/@chinlinblog/HJl4gBFLgx
筆者在測試使用Docker來建置的時候還沒有這篇文章,這篇文章非常的高價值,很推薦閱讀
簡單來說,HAPI FHIR在啟動前會讀取application.yaml,而最開始的application.yaml被封裝在Docker Image中,
我們只能透過映射的方式將設定檔覆寫,這個yaml內可以設定的選項非常的多,包含bulk、runtime upload ig等,或是匯入IG
後續在docker-compose.yml中的environment下方,將application放入目錄/configs中 SPRING_CONFIG_LOCATION: 'file:///configs/application.yaml'
另外在volumes欄位中補上
volumes:
- ./configs/:/configs
- ./data/:/data
即可,在docker compose up的時候docker會自己將這些文檔也納進去容器內。
對於匯入IG的正規做法來說,application.yaml內有提供implementationguides欄位可以設定要匯入的IG名稱、package的地址等,
雖然的確可以如同HAPI 官方提供的範例:
已註冊的IG:
swiss:
name: swiss.mednet.fhir
version: 0.8.0
reloadExisting: false
installMode: STORE_AND_INSTALL
未註冊的IG,提供URL
ips_1_0_0:
packageUrl: https://build.fhir.org/ig/HL7/fhir-ips/package.tgz
name: hl7.fhir.uv.ips
version: 1.0.0
但最好的方法是直接將需要的package.tgz下載到目錄裡(./data),透過映射送進容器中
twcore:
name: tw.gov.mohw.twcore
version: 0.3.2
reloadExisting: false
installMode: STORE_AND_INSTALL
packageUrl: file:///data/tw.gov.mohw.twcore-0.3.2.tgz
https://hackmd.io/@chinlinblog/HJl4gBFLgx
在看到這篇文章以前,我因為沒辦法讓HAPI FHIR正確的讀取到application.yaml,找出了另一種我認為覺得很荒謬但有效的匯入方法:
POST | http://localhost:8080/fhir/ImplementationGuide/$install
Body
{
"resourceType": "Parameters",
"parameter": [
{
"name": "npmContent",
"valueBase64Binary": base64(package.tgz)
}
]
}
簡單的來說,就是透過Postman,把你下載來的IG package.tgz轉成base64格式,整串貼上valueBase64Binary送出,
做這個操作要先注意HAPI FHIR的hapi.fhir.ig_runtime_upload_enabled 已經改成True
但這個方法不能用在比較大包的IG,有可能會產生連線逾時等其他問題。
除了IG以外,還有CodeSystem等Terminology需要匯入,
這又會有另一個問題了,像LOINC、SNOMED這種Terminology又大的離譜,但不匯入這些又沒辦法讓FHIR Server具有驗證能力,
這裡最好參照chinlin在文章中的做法,使用HAPI FHIR CLI來執行匯入。
其實設定HAPI FHIR跟FHIR Server這個東西完全是個超級大坑,光是這個主題就可以拉出30天來寫一次鐵人賽了
但筆者對於FHIR Server的理解與著墨還不夠深入,還沒辦法走這個主題。
如果用Maven來建HAPI FHIR會更簡單一些,因為任何實作更動都可以比Docker的流程更容易,
如果在Docker上想要修改HAPI FHIR本身的結構,最好的方法就是將更動完的結果自行打包成Image再使用,
兩條路其實都可以走,就看怎麼選擇。
關於HAPI FHIR的內容還很多,明天的內容會比較概要一點,因為在這個系列文中並不需要將FHIR Server等服務掛接到外部,
但還是會寫一篇文章談這些。