FHIR(ファイア)は、HL7 Internationalが定める医療情報交換の標準規格で、患者や検査結果を「リソース」というJSONの単位で表し、HTTPのREST APIでやり取りします。この記事では、日本で使われる基底仕様R4 4.0.1と、その上に日本向けの制約を足したJP Core 1.2.0の関係を整理し、JP_Patientで必須になる識別子やカナ氏名の書き方を公式作例から読み解きます。後半ではHAPI FHIRのJPAサーバーをDockerで起動し、作成・更新・検索・$validateをcurlで試す手順を載せました。電子カルテ情報共有サービスに送るデータの細則は電子カルテ情報共有サービスの2文書5情報のFHIR送信を扱った記事に分けています。
まとめ:FHIRは版を固定したJP Coreの上で動く検証環境から始める
FHIRの中身は、140種類を超えるリソースの定義と、それを読み書きするREST APIの規約です。日本の実装は基底仕様R4 4.0.1を土台に、JP Coreが識別子の書式やカナ氏名などの制約を加え、さらに電子カルテ情報共有サービス向けのJP-CLINSのような用途別の実装ガイドが重なる三層になっています。どの層のどの版に合わせるかを最初に決めないと、検証を通ったデータが相手先で弾かれます。
手を動かすなら、HAPI FHIRのJPAサーバーにJP Coreのパッケージを読み込ませ、公式作例のPatientをPOSTして$validateに掛けるところまでなら、数個のコマンドで届きます。本番のFHIRサーバーを自前で持つかどうかは、認証と監査ログまで作り込む覚悟があるかが判断の基準です。既存製品の連携機能で足りる場面では、サーバーを自作しないほうが安く済みます。
FHIRの位置づけとHL7 v2・CDAとの違いを実装者の目線で整理
FHIRは「Fast Healthcare Interoperability Resources」の略です。同じHL7の系譜にあるv2メッセージやCDA文書と比べると、Webの開発者がそのまま読める形に寄せた点が最大の違いです。
HL7 International公開のR4 4.0.1とR5 5.0.0の使い分け
HL7 FHIRの公式サイトのトップは、2026年11月時点でv5.0.0(R5)を現行版として表示しています。それでも国内の実装で選ぶのはR4 4.0.1です。JP Coreも、後述するJP-CLINSも、R4 4.0.1を基底仕様として作られているからです。
R4とR5ではリソースの要素名や必須の度合いが一部違い、R5のサーバーにR4前提のJSONを送ると読めない要素が出ます。新規に作るシステムでも、国内の相手先とつなぐ限りはR4で固定し、R5への移行はJP Coreが対応版を出してから検討する順番が安全です。
区切り文字で書くHL7 v2メッセージとJSONのリソースを比べた差分
院内の部門システム間で今も多く流れているHL7 v2は、「PID」「OBX」といったセグメントを縦棒で区切った1行の文字列で、項目の意味は位置で決まります。FHIR R4のv2との比較ページも、v2の要素をFHIRのリソースへ1対1で写せるわけではないと書いています。
FHIRでは同じ患者情報が "family": "山田" のように名前付きの要素になり、JSONパーサーと一般的なHTTPクライアントだけで扱えます。読み手を選ばないぶん、受け取る側の実装は軽くなります。ただし院内の既存の流れをFHIRに置き換える必要は必ずしもありません。v2とFHIRの使い分けは医療のデータ連携と院内4方式の比較で扱っています。
FHIRリソースの構造とJP Coreが日本向けに足した制約・拡張
FHIRの学習コストの大半は、リソースの種類と、それに国別・用途別の制約を重ねる「プロファイル」の仕組みを掴むことにあります。
Patient・Observationなど140種超のリソースと成熟度Nの意味
R4のリソース一覧は、リソースをFoundation・Base・Clinical・Financial・Specializedの5分類で並べ、140種類を超えます。各リソースには成熟度が付き、「N」はNormative(規範)として後方互換が保証された状態です。R4でNになっているのは、Patient・Observation・Bundle・OperationOutcomeなど一部に限られます。
実務で最初に触るのは、患者のPatient、検査値やバイタルのObservation、傷病名のCondition、処方のMedicationRequest、複数リソースを束ねるBundleの5つです。成熟度が低いリソースは版の改定で要素が変わりやすいので、採用前に一覧の表示を確かめます。
JP Core 1.2.0のJP_Patientで必須になる識別子と氏名カナ表記
JP CoreはFHIRを国内で使うための共通の実装ガイドで、公開履歴によれば最新版は2025年7月30日の1.2.0です。JP Core Patientプロファイルでは、基底仕様で任意だった identifier が1件以上の必須になり、その value も必須です。
公式作例のJSONを見ると、日本固有の書き方が3つ読み取れます。
- 患者IDの
systemはurn:oid:1.2.392.100495.20.3.51.に「1」と保険医療機関番号10桁を続けたOIDで、施設ごとに名前空間が分かれる - 氏名は
nameを2件持ち、漢字には拡張 iso21090-EN-representation の値IDE、カナには値SYLを付けて区別する - 人種はJP Core独自の拡張JP_Patient_Raceで表し、宗教と出生地はHL7標準の拡張をそのまま使う
特に識別子のOIDは、院内の患者番号をそのまま入れるだけでは足りず、医療機関番号を正しく組み込まないと他施設のデータと衝突します。患者マスタからFHIRを組み立てるときに最初に詰まるのがこの部分です。
基底仕様・JP Core・JP-CLINSの三層と版を固定する理由
JP Coreの上には、用途ごとの実装ガイドが載ります。電子カルテ情報共有サービス向けのJP-CLINSは、最新の1.2.0ではなく、2024年9月29日に公開された専用版1.1.2-clinsを土台にしています。同じ「JP Core準拠」でも、送り先によって参照する版が違うということです。
このため、FHIRのデータを作るシステムでは、基底仕様・JP Core・用途別ガイドの3つの版番号を設定値として持ち、検証にも同じ版のパッケージを使います。版を混ぜると、手元の検証では通ったのに相手のサーバーでプロファイル違反になる、という事故が起きます。
HAPI FHIRのJPAサーバーをDockerで起動して手元に検証環境を作る
FHIRの理解は、仕様書を読むより実際にリクエストを投げるほうが早く進みます。検証用のサーバーには、Java製のオープンソース実装HAPI FHIRのJPAサーバーが手軽です。
hapiproject/hapiイメージの起動とmetadataでの疎通を確かめる
HAPI FHIR JPA Server StarterのREADMEは、公式イメージを8080番で起動する方法を示しています。HAPI FHIRのGetting Startedにあるとおり組み込みのH2データベースを同梱しているため、外部のDBなしで起動できます。Docker Hubのタグ一覧では、2026年10月2日に出たv8.12.0-2がlatestと同じ版です。検証でも版はタグで固定します。
起動後、ブラウザで開くWebテスターは http://localhost:8080/、REST APIのベースURLは http://localhost:8080/fhir/ です。/fhir/metadata がCapabilityStatementを返せば、サーバーは受け付けられる状態にあります。
JP Core 1.2.0パッケージを起動時に読み込ませる環境変数の設定
JP_Patientで検証するには、JP Coreのパッケージをサーバーに入れておく必要があります。READMEは hapi.fhir.implementationguides 配下の設定を環境変数で渡す例を載せており、パッケージ名は配布ファイルの package.json にある jp-core.r4、版は 1.2.0 です。
# HAPI FHIR JPAサーバーをR4で起動し、JP Core 1.2.0を読み込ませる
docker run -d --name hapi-fhir -p 8080:8080 \
-e "hapi.fhir.fhir_version=R4" \
-e "hapi.fhir.implementationguides.jpcore.name=jp-core.r4" \
-e "hapi.fhir.implementationguides.jpcore.version=1.2.0" \
-e "hapi.fhir.implementationguides.jpcore.packageUrl=https://jpfhir.jp/fhir/core/1.2.0/jp-core.r4-1.2.0.tgz" \
-e "hapi.fhir.implementationguides.jpcore.installMode=STORE_AND_INSTALL" \
hapiproject/hapi:v8.12.0-2
# 起動には数十秒かかる。CapabilityStatementのFHIR版が4.0.1なら準備完了
curl -s http://localhost:8080/fhir/metadata | grep -o '"fhirVersion"[^,]*'
installModeのSTORE_AND_INSTALLは、パッケージを保存するだけでなくプロファイルなどの定義をサーバーに登録する指定です。H2はコンテナを消すとデータも消えるので、残したい場合はREADMEのPostgreSQL設定に切り替えます。
curlで試すFHIR REST APIの作成・読取・更新と版の管理
FHIR R4のRESTful APIの章は、作成がPOST、読取がGET、更新がPUTという素直な対応を定めています。Content-Typeは application/fhir+json を使います。
JP_Patient準拠の患者をPOSTし201とLocationヘッダを確かめる
公式作例から必要な要素だけを残した patient.json を用意します。meta.profile にJP_PatientのURLを書いておくと、後の検証でどのプロファイルに照らすかが明確になります。
{
"resourceType": "Patient",
"meta": { "profile": ["http://jpfhir.jp/fhir/core/StructureDefinition/JP_Patient"] },
"identifier": [
{ "system": "urn:oid:1.2.392.100495.20.3.51.11311234567", "value": "00000010" }
],
"name": [
{
"extension": [{ "url": "http://hl7.org/fhir/StructureDefinition/iso21090-EN-representation", "valueCode": "IDE" }],
"use": "usual", "text": "山田 太郎", "family": "山田", "given": ["太郎"]
},
{
"extension": [{ "url": "http://hl7.org/fhir/StructureDefinition/iso21090-EN-representation", "valueCode": "SYL" }],
"use": "usual", "text": "ヤマダ タロウ", "family": "ヤマダ", "given": ["タロウ"]
}
],
"gender": "male",
"birthDate": "1970-01-01"
}
# 同じ識別子の患者がいなければ作成する(条件付き作成)
curl -si -X POST http://localhost:8080/fhir/Patient \
-H "Content-Type: application/fhir+json" \
-H "If-None-Exist: identifier=urn:oid:1.2.392.100495.20.3.51.11311234567%7C00000010" \
--data-binary @patient.json | grep -iE "^HTTP|^Location|^ETag"
成功すると201 Createdが返り、Locationヘッダには [base]/Patient/[id]/_history/1 の形で新しいIDと版が入ります。If-None-Existは仕様上の条件付き作成で、一致する患者が1件あれば作成せずに200を返し、複数あれば412で処理を止める仕様です。連携処理の再送で同じ患者が二重登録される事故を、この1行で防げます。
If-MatchとETagで競合する更新を防ぐPUTと412が返る条件
FHIRのサーバーはリソースを更新するたびに versionId を1つ進め、ETagヘッダに W/"1" の形で返すよう推奨されています。更新時にこの値をIf-Matchに付けると、取得後に他の誰かが書き換えていた場合は更新が拒否されます。
# 取得した版(ここでは1)を前提に更新する。PATIENT_IDはPOSTのLocationから読み替える
curl -si -X PUT http://localhost:8080/fhir/Patient/PATIENT_ID \
-H "Content-Type: application/fhir+json" \
-H 'If-Match: W/"1"' \
--data-binary @patient_updated.json | grep -iE "^HTTP|^ETag"
PUTで送るJSONには "id": "PATIENT_ID" を入れておきます。1回目は成功してETagが W/"2" に変わり、同じコマンドをもう一度送ると版が合わず、更新は失敗です。R4の仕様は版の競合に409 Conflictか412 Precondition Failedを返すとしているので、クライアントは両方を「取り直してから再試行」の合図として扱います。過去の版は /Patient/PATIENT_ID/_history/1 で読めます。
$validateにJP_Patientのprofileを指定して適合性を検査する
保存とは別に、データがプロファイルに合っているかだけを確かめる操作が$validateです。profileパラメータにJP_PatientのURLを渡すと、結果がOperationOutcomeで返ります。
# 保存せずにJP_Patientへの適合だけを確かめる
curl -s -X POST \
'http://localhost:8080/fhir/Patient/$validate?profile=http://jpfhir.jp/fhir/core/StructureDefinition/JP_Patient' \
-H "Content-Type: application/fhir+json" \
--data-binary @patient.json
patient.json から identifier を消して送ると、JP_Patientで必須の要素が欠けている旨のエラーがissueに並びます。基底仕様のPatientとして検証しただけではこの欠落は見つかりません。JP Coreを読み込ませた意味はここにあります。
FHIR検索パラメータで患者と検査結果をまとめて取り出す書き方
FHIRの検索はURLのクエリで書きます。R4の検索の章に型ごとの書式があり、結果は常にBundleで返ります。
identifierのsystem|value指定とbirthdateのge・le接頭辞
識別子のようなtoken型は system|value の形で、OIDまで含めて指定すると施設をまたいでも一意に引けます。日付には ge(以上)、le(以下)、gt、lt などの接頭辞を付け、同じパラメータを2回並べると範囲指定になります。
# 施設のOIDと患者番号で1件に絞る(| は %7C にエンコード)
curl -s 'http://localhost:8080/fhir/Patient?identifier=urn:oid:1.2.392.100495.20.3.51.11311234567%7C00000010'
# 1970年代生まれの男性を10件ずつ、件数だけを先に確かめる
curl -s 'http://localhost:8080/fhir/Patient?birthdate=ge1970-01-01&birthdate=le1979-12-31&gender=male&_summary=count'
curl -s 'http://localhost:8080/fhir/Patient?birthdate=ge1970-01-01&birthdate=le1979-12-31&gender=male&_count=10'
_summary=count はリソースを返さずに件数だけをBundleのtotalに入れます。大量のデータを引く前に件数を見ておく目的は、取得を何回のバッチに分けるかを先に決めることです。2ページ目以降は、返ってきたBundleのlinkにあるURLをたどります。
_includeと連鎖検索でObservationから患者を一度に引くクエリ
検査結果の一覧画面を作るとき、Observationを取ってから患者を1件ずつ読みに行くと、往復の回数が件数分だけ増えます。参照先を同じBundleに入れて返させるのが _include で、参照先の条件で絞り込むのが連鎖検索です。
# 患者番号で検査結果を絞り、参照先のPatientも同じBundleに含める
curl -s 'http://localhost:8080/fhir/Observation?subject:Patient.identifier=urn:oid:1.2.392.100495.20.3.51.11311234567%7C00000010&_include=Observation:subject&_sort=-date'
同じBundleに入ったPatientは、entryのsearch.modeが include になっているため区別が可能です。逆向きに、患者を起点に関連する検査結果を含めたいときは _revinclude=Observation:subject を使います。どの検索パラメータに対応しているかはサーバーごとに違うため、metadataのCapabilityStatementで確かめてから画面の設計に入ります。
FHIRサーバーを自前で持つか既存製品の連携機能に任せるかの判断
検証環境がすぐ立つことと、本番でFHIRサーバーを運用できることは別の話です。ここでは、どこまでを自前で作るかの線引きを示します。
HAPI FHIRを本番に置くときに追加で要るDB・認証・監査ログ
Starterの既定構成は、検証のための最小構成です。本番に置くなら、少なくとも次の作り込みが要ります。
- H2から外部のPostgreSQLなどへの切り替えと、バックアップ・復旧手順の整備
- OAuth 2.0などによるアクセス制御。既定ではAPIに誰でも書き込める
- 誰がどの患者を参照したかを残す監査ログと、その保管期間の設計
- リソース数の増加に合わせた検索インデックスとサーバーのサイジング
特に認証と監査ログは、医療情報を扱う以上ガイドラインへの適合が問われる部分です。医療情報システムの安全管理の要件と、SS-MIX2の格納データからFHIR化できる範囲は医療情報システムとSS-MIX2・FHIR接続の実務で整理しています。
FHIRサーバーを自作しないほうがよい場面と開発を外に出す範囲
電子カルテのベンダがFHIRの出力機能を提供していて、送り先が電子カルテ情報共有サービスのように決まっているなら、自前のFHIRサーバーは要りません。院内に持つのは、送信前のデータを確かめる検証の仕組みだけで十分です。電子カルテ側の対応状況の見方は電子カルテの種類と標準仕様対応の判断にまとめています。
自前のFHIRサーバーやAPI層が要るのは、複数の部門システムのデータを集めて外部のアプリやPHRに出す場合、独自のシステムがデータの出どころになっている場合です。この層は、変換・検証・認証・監査を受け持つ独立したシステムとして切り出せます。要件を固めて見積もりたい場合は医療機関向けシステム開発で相談を受けています。
よくある質問
FHIRについて、検索の多い質問を5つ取り上げます。
FHIRとHL7は何が違うのですか?
HL7は医療情報の標準を作る団体(HL7 International)と、その団体が定めた規格群の総称です。FHIRはその規格群の1つで、v2メッセージやCDA文書の後に作られた、REST APIとJSONを前提にした規格に当たります。「HL7 FHIR」と並べて書くのは、HL7が定めたFHIRという意味です。院内では今もHL7 v2が多く使われており、FHIRがそれを置き換えたわけではありません。
FHIRの読み方と、R4・R5のどちらを使えばよいかを教えてください
読み方は「ファイア」です。版は、国内で使う限りR4 4.0.1を選びます。HL7の公式サイトはR5 5.0.0を現行版として表示していますが、JP Core 1.2.0も電子カルテ情報共有サービス向けのJP-CLINSも基底仕様はR4 4.0.1です。R5を使うのは、海外のサービスと接続するなど、相手先がR5を指定している場合に限られます。
JP Coreに準拠していれば電子カルテ情報共有サービスにそのまま送れますか?
送れません。電子カルテ情報共有サービスはJP Coreの上にあるJP-CLINSの規則に従う必要があり、土台のJP Coreも専用版の1.1.2-clinsです。Bundleの組み方や識別子の採番など、JP Coreには無い規則も加わります。具体的な送信仕様は電子カルテ情報共有サービスのFHIR送信の解説で扱っています。
FHIRのAPIを外部のスマホアプリやPHRに公開してもよいですか?
規格上は可能ですが、検証用の既定構成のまま公開してはいけません。HAPI FHIRのStarterは既定でアクセス制御を持たないため、OAuth 2.0による認可、患者本人に見せる範囲の制御、参照の監査ログを先に作ります。患者が自分の情報を管理するPHRとの役割分担はPHRと電子カルテ・EHRの役割分担の解説を参照してください。
FHIRの検証に使える公開のテストデータはありますか?
まずはJP Coreの実装ガイドにある公式作例が使えます。Patientのほか、Observationや処方などのプロファイルごとにJSONが公開されており、本文で使ったpatient.jsonもJP Core 1.2.0の作例から要素を絞ったものです。作例はプロファイルに適合する前提で作られているので、一部の要素を消したり書式を崩したりして、$validateがエラーを返すかを試す材料になります。
関連記事
- 電子カルテ情報共有サービスとは:2文書5情報のFHIR送信と接続方式を実装視点で解説:JP-CLINSのBundle構造と識別子、公式Validatorでの検証手順を扱っています。
- 医療情報システムとは?種類・構成と安全管理ガイドライン第7.0版対応、SS-MIX2とFHIR接続の実務【2026年版】:FHIRサーバーを置く前提になる安全管理の要件を確認できます。
- 医療のデータ連携|院内4方式と地域連携の構成・電子カルテ更新時の移行判断【2026年版】:HL7 v2・SS-MIX2・FHIRの使い分けを比較しています。
- 電子カルテとは?種類・機能一覧と比較軸・標準仕様対応の判断を解説【2026年】:電子カルテ製品のFHIR対応の見方が分かります。
- API連携とは?仕組み・データ連携との違い・導入判断までわかりやすく解説:REST APIによるシステム連携の基本を医療以外の例も含めて解説しています。