DEV Community

Cover image for EHR API の使い方
Akira
Akira

Posted on • Originally published at apidog.com

EHR API の使い方

TL;DR

EHR APIはEpic、Cerner、Athenahealthのようなシステムに保存されている患者の健康記録にアクセスします。ほとんどのEHRはFHIR(Fast Healthcare Interoperability Resources)をサポートしており、認証にはSMART on FHIR拡張機能付きのOAuth 2.0が使われます。テストにはApidogを利用し、FHIRリソースの検証やサンドボックスでの事前テストを行い、本番運用前に統合が患者データを正しく処理することを確認しましょう。

Apidogを今すぐ試す

はじめに

電子カルテ(EHR)は診断、投薬、検査結果、アレルギー、治療計画など患者ケアに関する全情報を含みます。病院や診療所はEpic、Cerner、AthenahealthなどのEHRプラットフォームにこのデータを保存しています。

医療アプリを構築する場合、これらのEHRと安全かつリアルタイムに連携する必要があり、CSVエクスポートだけでは不十分です。EHR連携にはAPIが必須ですが、医療APIはPHI(保護された健康情報)を扱い、HIPAA等の規制を順守する必要があります。

ほとんどのEHRベンダーはFHIRを標準APIとしてサポートしていますが、認証やデータマッピングには複雑さがあります。本記事では、ApidogによるFHIRリソースのテストやサンドボックス利用方法を含め、実践的な統合手順を解説します。

このガイドを読むことで、以下が実践できるようになります。

  • FHIRリソースのタイプと構造を理解
  • SMART on FHIRでの認証実装
  • 患者の人口統計・臨床データの取得
  • 患者リソースの作成・更新
  • サンドボックス環境でのテスト

FHIRを理解する

FHIR(Fast Healthcare Interoperability Resources)は医療APIの最新標準です。

  • リソース: Patient, Observation, Medicationなど医療概念ごとのデータ型
  • REST API: 標準操作(CRUD)
  • フォーマット: JSON・XML

ベースURL構造

https://ehr.example.com/fhir/r4/{resource-type}/{id}
Enter fullscreen mode Exit fullscreen mode

例:

GET https://ehr.example.com/fhir/r4/Patient/123
Enter fullscreen mode Exit fullscreen mode

FHIRバージョン

多くのEHRはFHIR R4(リリース4)を利用。一部システムはDSTU2を使いますが、本ガイドはR4準拠です。

リソースタイプ

リソース 目的
Patient 人口統計・管理データ
Practitioner 医療提供者
Organization 病院、診療所
Observation 検査結果、バイタルサイン
MedicationRequest 処方箋
Condition 診断・問題
Encounter 受診、入院
DocumentReference 臨床文書
AllergyIntolerance アレルギー・有害反応

FHIRリソースの構造

患者リソースの例

{
  "resourceType": "Patient",
  "id": "123",
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Smith",
      "given": ["John", "Michael"]
    }
  ],
  "gender": "male",
  "birthDate": "1985-03-15",
  "address": [
    {
      "use": "home",
      "line": ["123 Main St"],
      "city": "Boston",
      "state": "MA",
      "postalCode": "02101",
      "country": "USA"
    }
  ],
  "telecom": [
    {
      "system": "phone",
      "value": "555-123-4567",
      "use": "home"
    },
    {
      "system": "email",
      "value": "john.smith@example.com"
    }
  ],
  "identifier": [
    {
      "system": "http://hospital.example.org/mrn",
      "value": "MRN-123456"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

観察リソースの例

{
  "resourceType": "Observation",
  "id": "obs-123",
  "status": "final",
  "category": [
    {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/observation-category",
          "code": "vital-signs",
          "display": "Vital Signs"
        }
      ]
    }
  ],
  "code": {
    "coding": [
      {
        "system": "http://loinc.org",
        "code": "8480-6",
        "display": "Systolic blood pressure"
      }
    ]
  },
  "subject": {
    "reference": "Patient/123"
  },
  "effectiveDateTime": "2026-03-24T09:30:00Z",
  "valueQuantity": {
    "value": 120,
    "unit": "mmHg",
    "system": "http://unitsofmeasure.org",
    "code": "mm[Hg]"
  }
}
Enter fullscreen mode Exit fullscreen mode

SMART on FHIRによる認証

SMART on FHIRはOAuth 2.0に医療用途向け拡張を加えたもの。患者コンテキストやEHR固有のスコープ管理が可能です。

患者アクセス用のOAuthフロー

ステップ1: 認可URLを取得

GET https://ehr.example.com/fhir/r4/.well-known/smart-configuration
Enter fullscreen mode Exit fullscreen mode

レスポンス例:

{
  "authorization_endpoint": "https://ehr.example.com/oauth2/authorize",
  "token_endpoint": "https://ehr.example.com/oauth2/token",
  "scopes_supported": [
    "patient/*.read",
    "patient/*.write",
    "user/*.read",
    "launch/patient"
  ]
}
Enter fullscreen mode Exit fullscreen mode

ステップ2: ユーザーを認可にリダイレクト

https://ehr.example.com/oauth2/authorize?
  response_type=code&
  client_id=YOUR_CLIENT_ID&
  redirect_uri=https://yourapp.com/callback&
  scope=patient/*.read&
  state=random_state_value
Enter fullscreen mode Exit fullscreen mode

ステップ3: コードをトークンに交換

curl -X POST "https://ehr.example.com/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=https://yourapp.com/callback" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"
Enter fullscreen mode Exit fullscreen mode

レスポンス例:

{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "patient/*.read",
  "patient": "123"
}
Enter fullscreen mode Exit fullscreen mode

patientフィールドが患者IDを示します。

SMARTスコープ

スコープ アクセス内容
patient/*.read 患者データ全体の読み取り
patient/Patient.read 人口統計データのみ読み取り
patient/Observation.read 観察データのみ読み取り
user/*.read 認証ユーザーのデータ全体読み取り
launch/patient 患者コンテキストでアプリを起動

患者データの照会

患者の人口統計データ取得

curl -X GET "https://ehr.example.com/fhir/r4/Patient/123" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

観察データ検索

curl -X GET "https://ehr.example.com/fhir/r4/Observation?patient=123&category=vital-signs" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

レスポンスはBundle形式:

{
  "resourceType": "Bundle",
  "type": "searchset",
  "total": 5,
  "entry": [
    {
      "resource": { ... Observation resource ... }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

一般的な検索パラメータ

# 日付範囲指定
GET /Observation?patient=123&category=laboratory&date=gt2026-01-01

# LOINCコード指定
GET /Observation?patient=123&code=http://loinc.org|8480-6

# 投薬
GET /MedicationRequest?patient=123&status=active

# 診断
GET /Condition?patient=123&clinical-status=active

# 受診記録
GET /Encounter?patient=123&type=AMB
Enter fullscreen mode Exit fullscreen mode

ページネーション

GET /Observation?patient=123&_count=20
Enter fullscreen mode Exit fullscreen mode

レスポンス例:

{
  "link": [
    {
      "relation": "next",
      "url": "https://ehr.example.com/fhir/r4/Observation?patient=123&_count=20&page=2"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

リソースの作成と更新

観察データの作成

curl -X POST "https://ehr.example.com/fhir/r4/Observation" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/fhir+json" \
  -d '{
    "resourceType": "Observation",
    "status": "final",
    "code": {
      "coding": [{
        "system": "http://loinc.org",
        "code": "8480-6",
        "display": "Systolic blood pressure"
      }]
    },
    "subject": {
      "reference": "Patient/123"
    },
    "effectiveDateTime": "2026-03-24T09:30:00Z",
    "valueQuantity": {
      "value": 118,
      "unit": "mmHg",
      "system": "http://unitsofmeasure.org",
      "code": "mm[Hg]"
    }
  }'
Enter fullscreen mode Exit fullscreen mode

患者の更新

curl -X PUT "https://ehr.example.com/fhir/r4/Patient/123" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/fhir+json" \
  -d '{
    "resourceType": "Patient",
    "id": "123",
    "name": [{
      "family": "Smith",
      "given": ["John", "Michael"]
    }],
    "telecom": [{
      "system": "phone",
      "value": "555-999-8888",
      "use": "home"
    }]
  }'
Enter fullscreen mode Exit fullscreen mode

EHRベンダー固有の詳細

Epic

  • ベースURL: https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/
  • サンドボックス: https://fhir.epic.com/test/api/FHIR/R4/
  • ドキュメント: https://fhir.epic.com

Epic本番環境アクセスにはアプリ登録が必須です。

Cerner (Oracle Health)

Athenahealth

  • ベースURL: https://api.platform.athenahealth.com/fhir/r4/{practice-id}
  • サンドボックス: 開発者プログラム経由で提供
  • ドキュメント: https://docs.athenahealth.com

Apidogでのテスト

医療APIではテストが極めて重要です。患者データは機密性が高いため、サンドボックスやリソース検証を徹底しましょう。

FHIR APIテストイメージ

1. 公開サンドボックス利用

下記の公開FHIRサンドボックスでテストを行います。

# HAPI FHIR(オープンソース)
https://hapi.fhir.org/baseR4

# SMART Health ITサンドボックス
https://launch.smarthealthit.org
Enter fullscreen mode Exit fullscreen mode

2. FHIRリソース検証例 (Apidog テストスクリプト)

pm.test('Resource is valid Patient', () => {
  const response = pm.response.json()
  pm.expect(response.resourceType).to.eql('Patient')
  pm.expect(response.id).to.exist
  pm.expect(response.name).to.be.an('array')
})

pm.test('Observation has required fields', () => {
  const resource = pm.response.json()
  pm.expect(resource.status).to.exist
  pm.expect(resource.code).to.exist
  pm.expect(resource.subject).to.exist
})
Enter fullscreen mode Exit fullscreen mode

3. 認証フローのテスト

SMART構成情報を環境変数として設定します。

AUTHORIZATION_ENDPOINT: https://ehr.example.com/oauth2/authorize
TOKEN_ENDPOINT: https://ehr.example.com/oauth2/token
CLIENT_ID: your_client_id
CLIENT_SECRET: your_client_secret
SCOPE: patient/*.read
Enter fullscreen mode Exit fullscreen mode

コンプライアンスに関する考慮事項

HIPAA

米国で医療アプリを運用する場合、以下の点に配慮しましょう。

  • データ伝送: TLS 1.2以上を必須
  • データ保存: 保存時の暗号化
  • アクセス制御: 監査ログと最小権限
  • BAA契約: EHRベンダーとビジネスアソシエイト契約を締結

SMART on FHIRのセキュリティ

  • アクセストークンは有効期限あり(通常1時間)
  • 長期セッションにはリフレッシュトークンを利用
  • 患者コンテキストはトークンスコープに紐づく
  • ログアウト時はトークンの失効が必要

データ最小化

必要なスコープのみ取得しましょう。

  • 良い例: patient/Observation.read
  • 避けるべき: patient/*.read(不要な場合)

一般的なエラーと修正

401 認証エラー

  • 原因: トークン期限切れ/無効
  • 対策: リフレッシュトークンで更新

403 アクセス禁止

  • 原因: スコープ不足
  • 対策: 必要スコープを確認し認可リクエスト時に追加

404 リソース未検出

  • 原因: 患者やリソースが存在しない
  • 対策: ID・患者コンテキストを再確認

422 バリデーションエラー

  • 原因: FHIRリソース検証失敗
  • 対策: 必須フィールド・用語の不足を修正

例:

{
  "resourceType": "OperationOutcome",
  "issue": [{
    "severity": "error",
    "code": "required",
    "details": {
      "text": "Observation.status is required"
    }
  }]
}
Enter fullscreen mode Exit fullscreen mode

代替案と比較

機能 Epic Cerner Athenahealth OpenEMR
FHIR R4 部分的
SMART on FHIR いいえ
サンドボックス 制限あり 自己ホスト
APIドキュメント 素晴らしい 良い 良い 基本的
市場シェア 大規模病院 医療システム 小規模診療所 オープンソース

Epic・Cernerは大規模医療機関向け、Athenahealthは小規模診療所向け、OpenEMRはOSSですがAPIサポートは限定的です。

実世界のユースケース

  • 患者ポータル: Epicから患者データを取得し、検査結果や予約情報を表示するポータル。SMART on FHIR認証+FHIR API利用。
  • 臨床研究: 製薬会社が複数病院のFHIR APIを照会し、基準に合致する患者を同意管理下で抽出。
  • リモートモニタリング: 遠隔医療会社が患者のバイタルサインをFHIR ObservationでEHRへ記録し、臨床医へ即時共有。

まとめ

本記事の要点:

  • FHIRは医療APIの標準
  • 各リソースは患者・観察など医療概念を表現
  • SMART on FHIRでOAuth認証を実装
  • EHRごとの固有事項に注意
  • サンドボックスで十分なテストを

次のステップ:

  1. HAPI FHIR公開サンドボックスを試す
  2. 必要なFHIRリソースタイプを特定
  3. EHR開発者プログラムに登録
  4. モック患者データでApidogテスト
  5. HIPAA対応のデータ処理を実装

ApidogでFHIR APIをテスト - 無料

FAQ

FHIRとHL7 v2の違いは?

HL7 v2は古いメッセージング標準(病院間インターフェース用)、FHIRはREST APIベースの新標準です。新規統合はFHIRが主流、レガシーではHL7 v2も利用されます。

EHR APIにBAA契約は必要?

PHIを扱う場合は必須です。ビジネスアソシエイト契約(BAA)はEHR業者と締結が必要です。必ずEHRベンダーのコンプライアンス部門に相談しましょう。

EpicのFHIR APIにアクセスするには?

Epic App Orchardマーケットプレイスで登録。テストには公開サンドボックス、本番アクセスには病院の承認が必要です。

患者コンテキストとは?

SMART on FHIRトークンに患者IDが含まれることで、API呼び出しがその患者のデータに限定されます。

EHRにデータを書き込める?

観察データ作成や人口統計更新は可。診断や投薬の書き込みは通常、追加の臨床承認が必要です。

用語コードはどう扱う?

FHIRリソース作成時は標準用語を使用:

  • 検査・観察: LOINC
  • 臨床概念: SNOMED CT
  • 診断: ICD-10
  • 投薬: RxNorm

国際的な医療利用は?

FHIRはグローバル規格。各国ごとに実装ガイドがあり、米国はUS Coreプロファイルを利用します。自国仕様を確認してください。

Top comments (0)