iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0

本文同步發表於個人部落格:SMART on FHIR 新地圖


左邊是一張破損的舊羊皮紙地圖,只畫了單一醫院內部的走廊與病房,路線走到邊緣就斷了;右邊是一張現代的深藍導航地圖,發光的路線把多家醫院、一支手機與一個鑰匙圖示串在一起,並且延伸出畫面之外
火線超人動工之前,我先面對一個很現實的問題:要用什麼方式跟醫院的系統要資料?當時面前有三條路。一是傳統路線,跟每家醫院談專屬介接,規格各談各的;二是自己定義一套 API,請對方配合;三是跟上政府與國際都在推動的標準。

前兩條路的下場,我在醫院看過太多次了。專屬介接做得出來,但每多接一家醫院就得重做一次,維護成本隨規模膨脹到讓人懷疑人生;自訂 API 則是把同樣的痛苦原封不動丟給對方,對方也不會太開心。

但真正讓我放棄前兩條路的,不是麻煩,是方向。那些不走標準的作法,用的都是同一張舊地圖:地圖上畫的是一家醫院的內部,資訊室在哪、哪台機器接哪台、規格跑得動就好。問題是,現在要去的地方不在這張圖上,資料要跨院流動、app 要跑在病人自己的手機上、同不同意由病人親手點下去。拿舊地圖走這幾條路,不是走錯,是圖上根本沒有這幾個地名;再熟悉的老路,也載不了你到一個沒被畫進去的目的地。

所以火線超人從一開始就全部走 SMART on FHIR 標準。倒不是我看得準,而是 FHIR 本來就是政府在推的方向;我只是身在這個醫療場域裡,天天看得到跨院資料交換的需求,自然就往這條路走。

不過「走標準」講起來只有一句話,真的點開規格才知道,難的不是份量,是不知道從哪裡進去。FHIR 官方首頁把內容分成五個層級、十幾個模組、一百多種資源,第一個卡住你的問題會是「那我到底該先看哪一頁」;好不容易點進 Patient 想看欄位,一個資源又分成 Content、Examples、Search Params、Profiles 等八個分頁。SMART App Launch 那邊更乾脆,讀沒幾段就把你丟去 OAuth 2.0 的 RFC,那份 RFC 再把你丟去下一份,繞一圈回來還得先搞清楚自己走的是 app 還是後端服務那條岔路。

FHIR 官方首頁的 Level 1 到 Level 5 總覽,每一層底下再分成 Foundation、Conformance、Terminology、Clinical、Financial 等模組

這是 FHIR 首頁的全貌,五個層級、十幾個模組,每個藍字都是一份文件。點進其中一個資源也沒有比較輕鬆,光是 Patient 一頁就分成這幾個分頁:

Patient 資源頁頂端的分頁列,依序是 Content、Examples、Detailed Descriptions、Mappings、Operations、Search Params、Profiles、Extensions、R4 Conversions

每一頁單獨看都寫得很清楚,問題是它們是一張互相連結的網,不是一條讀得完的路。FHIR、SMART、OAuth 2.0、OpenID Connect,這幾個名詞雖然有聽過,但一次同時擠到面前時,也費了大把勁才把它們的關係理清楚。今天這篇,就是當年我很希望有人直接塞給我的那張新地圖。

新地圖上的四個標準

先看全景,再逐層拆:

SMART App Launch(醫療 app 的啟動與授權規範)
 ├── FHIR(資料層:醫療資料長什麼樣、怎麼存取)
 ├── OAuth 2.0(授權層:app 憑什麼拿資料)
 └── OpenID Connect(身分層:操作的人是誰)
      └── 全部站在 HTTP / REST / JSON 之上

FHIR 由 HL7 組織制定,把醫療資料標準化成一個個 Resource,用 RESTful API 搭配 JSON 存取。重點:它只管資料,不管你有沒有資格拿。授權?不關它的事。

OAuth 2.0 是網路世界通用的授權框架。你用 Google 帳號登入第三方服務、授權它讀你的行事曆,背後就是這套。核心概念是代理授權:使用者不用把密碼交出去,而是由授權伺服器發一張有範圍限制的通行證(access token)給 app。

OpenID Connect 站在 OAuth 2.0 上面補了身分這層。OAuth 只回答「這張通行證能做什麼」,OIDC 進一步回答「拿通行證的人是誰」。

SMART App Launch 不是全新發明,而是把上面三個標準串成一套組合技:規定它們在醫療情境下要怎麼搭配。授權範圍用 patient/Observation.read 這種一看就懂的語法寫、app 啟動時怎麼知道「現在在看哪位病人」、伺服器要在哪個端點公告自己會什麼。我的比喻是:OAuth 2.0 規定了「訪客證」這種東西該怎麼發,但沒說醫院的訪客證上該印什麼。SMART App Launch 補上的就是這一段。這張證只能進哪幾間病房、上面要寫明你現在看的是哪位病人、證要去哪個櫃台領。

三方角色分工

地圖上還有三個角色要認識,這 30 天他們會天天出場:

角色 OAuth 術語 白話文 火線超人的對應
app client 你要寫的東西 火線超人本體
FHIR server resource server 醫院的資料出口 各醫院的 FHIR 端點
授權伺服器 authorization server 發通行證的守門員 各醫院附屬的授權端點

那常聽到的 EHR(電子病歷系統)在哪?EHR 是醫院資訊系統的整體,FHIR server 和授權伺服器通常是它對外的門面。對 app 開發者來說,你面對的永遠是那兩個標準化的端點,門面後方的系統長什麼樣子,你不需要知道,也管不著。這正是標準化的好處。

不過「門面」這個詞講得太輕鬆了。醫院不會把 FHIR server 直接插上網際網路,那兩個端點通常擺在 DMZ,前面還疊著防火牆、WAF、反向代理,嚴謹一點的還會要求來源 IP 白名單、憑證或走 VPN 才連得進去。你打的那個網址,第一個接到請求的往往不是 FHIR server 本人,而是最外層的關卡。

這件事對寫程式的人很有感:WAF 是照通用攻擊特徵在看流量的,FHIR 那些落落長的 search 參數、$ 開頭的 operation,偶爾會被判定成可疑而攔下來;中間層也可能改寫或吃掉某些 header。除錯時記得先分清楚是哪一層在說話:同樣是 403,可能是授權範圍不夠,也可能是你根本還沒走進門。判斷方法很簡單:FHIR server 拒絕你會回一份 OperationOutcome,WAF 只會丟給你一頁看不出所以然的錯誤頁。這兩種 403 的解法差別很大,day27 會專門聊醫療 app 的安全思維,今天先讓這幾道關卡在地圖上標示起來。

生態系:這套標準有多少人在用

這不是誰的眼光獨到,而是整個生態系共同的走向。美國透過法規要求主要的電子病歷系統開放 SMART on FHIR API,Epic、Oracle Health 這些大型 EHR 廠商都有自己的 app 上架機制;寫一次 app,理論上可以跑在不同廠牌的系統上。

台灣的腳步也在加快:TWCore 實作指引定義了在地化的 FHIR 規範,健保與各醫院陸續建置 FHIR 端點,台灣 50 這類競賽把散落各處的實作者聚在一起。day25 我會專門聊台灣生態,這裡先記一件事:你在這個系列學的不是台灣限定的利基技能,是全球通用的標準

跟著做:把兩份官方規格加入書籤

今天的任務很輕鬆,認識兩份接下來一個月會被我們翻到爛的文件,各找一樣東西:

  1. SMART App Launch 官方規格 https://hl7.org/fhir/smart-app-launch ,找到 App Launch 章節裡的授權流程圖,長這樣:

SMART App Launch 的授權時序圖,App、EHR with Authorization Server、FHIR Server 三條泳道之間依序來回 launch request、discovery、authorization request、access token request 與 request resources

今天不用看懂,知道它存在就好,day05 到 day09 我們會把這張圖一步一步拆完。

  1. FHIR 官方入口 https://hl7.org/fhir ,點進 Resources 清單,找到 Patient,看一眼它的欄位表。明天就要動手抓它了。

順便觀察一件事:兩份規格都標著版本號(FHIR 有 R4、R5,SMART 有 1.0、2.0)。標準是活的、會演進,寫 app 時標明你支援哪個版本很重要,這個坑我們之後再聊。

小結

今天把四個標準放進同一張新地圖:FHIR 管資料、OAuth 2.0 管授權、OpenID Connect 管身分,SMART App Launch 把三者組裝成醫療 app 的標準啟動流程;也認識了 app、FHIR server、授權伺服器這三位常駐角色。圖上的地名先認熟,接下來 30 天才走得動。

明天進入動手的第一步:直接用 HTTP 把 FHIR 資源抓下來,親手摸摸 Patient 和 Observation 長什麼樣子。


上一篇
Day01 - 為什麼是 SMART on FHIR
下一篇
Day03 - FHIR 資源快速入門
系列文
SMART on FHIR 開發之路:30 天做一個跨醫院的 app4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言