Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
FHIR R4를 사용하여 의료 기록 저장 방법
튜토리얼: Patient, 혈압 Observation 및 Condition 생성, 트랜잭션 사용, 기록 검색, 기록으로 업데이트 및 출처 읽기 — curl을 사용한 모든 요청 및 실제 응답, 무료 샌드박스에서.
이 튜토리얼에서는 HL7 FHIR R4 리소스로 작은 의료 기록을 저장합니다. 즉, Patient, 혈압 Observation, 진단 Condition을 생성한 다음, 환자와 측정값을 하나의 트랜잭션으로 묶습니다. 그런 다음 이를 검색하고, 이전 버전을 잃지 않고 진단을 업데이트하며, 누가 무엇을 작성했는지 출처를 읽습니다. 모든 요청은 무료 Anpheros 샌드박스에 대한 일반 curl이며, 표시되는 모든 응답은 API가 반환하는 내용입니다.
FHIR이 처음이라면 먼저 FHIR 플랫폼에서 개념을 읽어보세요. 이 페이지는 실습 부분입니다.
대부분의 레코드가 시작하는 세 가지 리소스
| 리소스 | 내용 | 코딩 방식 |
|---|---|---|
Patient |
레코드가 누구에 관한 것인지: 이름, 생년월일, 성별, 다른 시스템의 식별자 | 귀하의 식별자 시스템 |
Observation |
측정되거나 보고된 모든 것: 활력 징후, 검사 결과, 체중, 증상 점수 | LOINC, UCUM 단위 |
Condition |
진단 또는 건강 문제, 시간에 따른 상태 포함 | ICD-10 (라이선스 플래그 뒤에 SNOMED CT) |
Medications (MedicationStatement), allergies (AllergyIntolerance), immunizations 및 documents도 동일한 패턴을 따릅니다. 26가지 지원 리소스 유형은 /fhir/R4/metadata의 capability statement에 나열되어 있습니다.
시작하기 전에
platform.anpheros.com/dashboard에서 Get a sandbox key를 클릭하여 샌드박스 키(sk_test_…)를 발급받으세요. 이곳에서 생성하는 모든 데이터는 실제 환자 데이터가 아니며, 다른 프로젝트에 노출되지 않습니다.
export BASE=https://platform.anpheros.com/fhir/R4
export KEY=sk_test_…
1단계: 환자 생성
curl -X POST "$BASE/Patient" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" -d '{
"resourceType": "Patient",
"identifier": [{"system": "https://clinic.example/mrn", "value": "MRN-10442"}],
"name": [{"family": "Marin", "given": ["Ioana"]}],
"gender": "female",
"birthDate": "1979-04-12"
}'
서버가 할당한 id와 버전을 포함한 201 Created:
{"resourceType": "Patient",
"identifier": [{"system": "https://clinic.example/mrn", "value": "MRN-10442"}],
"name": [{"family": "Marin", "given": ["Ioana"]}], "gender": "female", "birthDate": "1979-04-12",
"id": "d09e3942-ed86-4458-b099-fa674ab21b84",
"meta": {"versionId": "1", "lastUpdated": "2026-10-12T20:16:51.043Z"}}
자신이 제어하는 system(여기서는 클리닉의 기록 번호)과 함께 자신의 id를 identifier에 보관하여 GET $BASE/Patient?identifier=https://clinic.example/mrn|MRN-10442로 환자를 항상 다시 찾을 수 있도록 하십시오. FHIR id는 플랫폼의 것이며 프로젝트별로 고유합니다. 다른 프로젝트에서는 동일한 사람을 다른 id로 볼 수 있습니다.
export PID=d09e3942-ed86-4458-b099-fa674ab21b84
2단계: 측정값을 Observation으로 저장하기
혈압은 두 개의 구성 요소(수축기 및 이완기)를 가진 하나의 관찰 항목이며, 각 구성 요소는 고유한 LOINC 코드를 가집니다. 누가 측정했는지 명시하세요. 여기서는 가정용 장치입니다.
curl -X POST "$BASE/Observation" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
-H "X-Anpheros-Author-Type: device" -H "Idempotency-Key: bp-2026-10-10-0830" -d '{
"resourceType": "Observation",
"status": "final",
"category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
"code": {"coding": [{"system": "http://loinc.org", "code": "85354-9", "display": "Blood pressure panel"}]},
"subject": {"reference": "Patient/'$PID'"},
"effectiveDateTime": "2026-10-10T08:30:00Z",
"component": [
{"code": {"coding": [{"system": "http://loinc.org", "code": "8480-6"}]},
"valueQuantity": {"value": 138, "unit": "mmHg", "system": "http://unitsofmeasure.org", "code": "mm[Hg]"}},
{"code": {"coding": [{"system": "http://loinc.org", "code": "8462-4"}]},
"valueQuantity": {"value": 88, "unit": "mmHg", "system": "http://unitsofmeasure.org", "code": "mm[Hg]"}}
]
}'
응답은 id 및 meta.versionId: "1"이 포함된 저장된 리소스입니다. 유용한 기록을 위해 세 가지 세부 정보가 중요합니다.
- 레이블이 아닌 코드.
85354-9는 모든 FHIR 시스템에서 "혈압 패널"을 의미합니다. 텍스트로 된 "BP"는 그렇지 않습니다.GET /v1/terminology/loinc?q=blood pressure(FHIR 코드 시스템)을 사용하여 코드를 조회하세요. - UCUM 단위 (
mm[Hg],kg,mg/dL)를valueQuantity.code에 포함하여 값을 비교하고 변환할 수 있도록 합니다. Idempotency-Key. 타임아웃 후 재시도하면 판독값을 두 번 저장하는 대신 첫 번째 응답을 반환합니다.
검사 결과는 category laboratory 및 일반적으로 referenceRange이 포함된 동일한 리소스입니다. 전체 검사 보고서를 가져오려면 FHIR 기록으로 검사 결과 가져오기를 참조하세요.
3단계: 진단을 Condition으로 기록하기
curl -X POST "$BASE/Condition" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
-H "X-Anpheros-Author-Type: practitioner" -d '{
"resourceType": "Condition",
"subject": {"reference": "Patient/'$PID'"},
"clinicalStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "active"}]},
"verificationStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status", "code": "confirmed"}]},
"code": {"coding": [{"system": "http://hl7.org/fhir/sid/icd-10", "code": "I10", "display": "Essential (primary) hypertension"}]},
"onsetDateTime": "2026-03-02"
}'
clinicalStatus (active, resolved, in remission)와 verificationStatus (confirmed, provisional)은 의도적으로 분리되어 있습니다. 의심되는 진단은 확정된 진단과 다르며, 해결된 문제는 여전히 기록의 일부입니다.
4단계: 단일 트랜잭션으로 관련 리소스 생성
예를 들어 클리닉 시스템에서 환자와 첫 번째 측정값이 함께 도착하는 경우, transaction 번들로 전송합니다. 모든 것이 저장되거나 아무것도 저장되지 않습니다. 새 리소스 간의 참조는 서버가 교체하는 임시 urn:uuid: ID를 사용합니다.
curl -X POST "$BASE" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" -d '{
"resourceType": "Bundle", "type": "transaction",
"entry": [
{"fullUrl": "urn:uuid:9f1c0d1e-0000-4000-8000-000000000001",
"resource": {"resourceType": "Patient", "name": [{"family": "Stan", "given": ["Mihai"]}], "gender": "male", "birthDate": "1990-02-01"},
"request": {"method": "POST", "url": "Patient"}},
{"resource": {"resourceType": "Observation", "status": "final",
"category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
"code": {"coding": [{"system": "http://loinc.org", "code": "29463-7", "display": "Body weight"}]},
"subject": {"reference": "urn:uuid:9f1c0d1e-0000-4000-8000-000000000001"},
"effectiveDateTime": "2026-10-10",
"valueQuantity": {"value": 82.4, "unit": "kg", "system": "http://unitsofmeasure.org", "code": "kg"}},
"request": {"method": "POST", "url": "Observation"}}
]
}'
transaction-response은 리소스당 하나의 항목을 가지며, "status": "201 Created", 해당 location 및 저장된 리소스를 포함합니다. Observation의 subject는 이제 실제 Patient/fad3665a-…을 가리킵니다.
5단계: 검색
curl "$BASE/Observation?patient=$PID&code=http://loinc.org|85354-9&date=ge2026-10-01&_sort=-date" \
-H "Authorization: Bearer $KEY"
검색 결과로 searchset Bundle을 받게 되며, 여기에는 total와 일치하는 리소스가 최신순으로 포함됩니다. 자주 사용하게 될 다른 검색은 다음과 같습니다: Condition?patient=$PID&clinical-status=active, Observation?patient=$PID&category=laboratory, 그리고 전체 기록을 위한 Patient/$PID/$everything입니다.
6단계: 기록 손실 없이 업데이트
고혈압이 해결되었습니다. 상태를 변경하고 종료 날짜를 추가하며, 다른 사람의 변경 사항을 덮어쓰지 않도록 읽은 버전을 If-Match과 함께 사용합니다.
curl -X PUT "$BASE/Condition/$CID" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
-H 'If-Match: W/"1"' -d '{ …the same Condition…, "clinicalStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "resolved"}]}, "abatementDateTime": "2026-10-11" }'
200 OK을 ETag: W/"2"과 함께 사용합니다. 다른 쓰기가 먼저 발생하면 412 오류가 발생하며 다시 읽어야 합니다. 이전 버전은 그대로 유지됩니다.
curl "$BASE/Condition/$CID/_history" -H "Authorization: Bearer $KEY"
두 버전 모두 반환합니다. versionId 2 (resolved) 및 1 (active)입니다. GET $BASE/Condition/$CID/_history/1은 이전 버전을 읽습니다. 레코드의 어떤 것도 조용히 덮어쓰이지 않습니다.
7단계: 누가 무엇을 작성했는지 확인
모든 작성은 Provenance 리소스를 생성합니다. 혈압 측정값의 경우:
curl "$BASE/Provenance?target=Observation/$OBS" -H "Authorization: Bearer $KEY"
{"resourceType": "Provenance",
"target": [{"reference": "Observation/d83d9075-…/_history/1"}],
"recorded": "2026-10-12T20:16:51.056000Z",
"activity": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/v3-DataOperation", "code": "CREATE"}]},
"agent": [{"type": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type", "code": "author"}]},
"who": {"identifier": {"system": "https://anpheros.com/fhir/CodeSystem/author-type", "value": "device"}, "display": "proj_…"},
"onBehalfOf": {"identifier": {"system": "https://anpheros.com/fhir/sid/organization", "value": "org_…"}, "display": "…"}}]}
전송한 작성자 유형(device)은 프로젝트 및 조직과 함께 기록됩니다. 작성자의 신원을 명시하려면 X-Anpheros-Author-Ref: Practitioner/<id>을 전송하십시오.
8단계: 요약으로서의 기록
curl "$BASE/Patient/$PID/\$summary" -H "Authorization: Bearer $KEY"
International Patient Summary(국제 환자 요약)를 반환합니다. 이는 document Bundle이며 Composition로 시작하고, 위 리소스들로부터 구성된 Problems, Medications, Allergies, Vital signs와 같은 섹션을 포함합니다. 이는 다른 시스템에 전달하거나 의사에게 인쇄하기 위한 형식입니다 (FHIR platform).
FHIR 없이 JSON을 선호하시나요?
동일한 데이터는 더 간단한 REST 뷰, /v1를 통해서도 이용 가능하며, 동일한 ID를 사용합니다. POST /v1/patients/{id}/observations은 {"code": "85354-9", "category": "vital-signs", "effective_at": "…", "components": […]}을 가져와 동일한 FHIR Observation을 저장합니다. 코드에 더 적합한 것을 사용하세요. Medical data API 및 SDKs를 참조하세요.
자주 묻는 질문
의료 기록을 저장하는 가장 좋은 방법은 무엇인가요?
코드로 작성되고 버전이 관리되며 각 항목을 누가 작성했는지 기록된 리소스입니다. HL7 FHIR R4는 구조(Patient, Observation, Condition 등), LOINC 및 ICD-10과 같은 표준 코드 시스템, 기록 기능을 제공합니다. FHIR 백엔드는 검색, 동의 및 출처 관리를 추가합니다.
FHIR을 사용하기 위해 FHIR 서버가 필요한가요?
FHIR 리소스를 저장하고 검색하며 누가 읽을 수 있는지 강제할 수 있는 곳이 필요합니다. 자체적으로 오픈 소스 FHIR 서버를 실행하거나 Anpheros와 같은 관리형 서버를 사용할 수 있습니다. Anpheros와 다른 FHIR 서버 비교에서 옵션을 비교하고, FHIR 대 사용자 지정 의료 데이터베이스에서는 자체 스키마를 구축하는 방법을 다룹니다.
FHIR에서 혈압을 어떻게 저장하나요?
코드 LOINC 85354-9를 가진 하나의 Observation와 두 개의 component 항목: 수축기 8480-6 및 이완기 8462-4로 저장하며, 각 항목은 mm[Hg]의 valueQuantity를 가집니다.
저장된 리소스를 변경할 수 있나요?
네, PUT 및 If-Match를 사용하여 변경할 수 있습니다. 각 변경은 새 버전을 생성하며, 이전 버전은 _history를 통해 계속 읽을 수 있고, Provenance는 각 변경을 누가 했는지 기록합니다. 삭제는 소프트 삭제이며 기록을 유지합니다.
관련 자료
- FHIR 플랫폼: 개념, 리소스 유형 및 작업
- FHIR 코드 시스템: LOINC, ICD-10, ATC, UCUM
- FHIR 레코드에 실험실 결과 가져오는 방법
- Medical data API: 동일한 데이터의 더 간단한 REST 뷰
- 무료 FHIR 데이터베이스 및 샌드박스
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card