Chuyển đến nội dung chính

Bài 3: Cài đặt môi trường phát triển FHIR

Cài đặt HAPI FHIR Server (Docker), FHIR Test Server công khai, Postman Collection cho FHIR, FHIR Shorthand (FSH) và SUSHI, VS Code extensions cho FHIR, chạy thử các thao tác CRUD đầu tiên.

🏗️ Kiến trúc — Bài 3 Bài 3: Cài đặt môi trường phát triển FHIR

HL7 FHIR - Chuẩn Dữ liệu Y tế từ Cơ bản đến Nâng cao

Phần 1: Nền tảng HL7 và FHIR

xdev.asia

Xem bản video

1. Tổng quan các công cụ cần thiết

Để thực hành FHIR hiệu quả, bạn cần chuẩn bị các công cụ sau:

Công cụMục đíchBắt buộc?
HAPI FHIR ServerFHIR Server local để thực hànhCó
DockerChạy HAPI FHIR ServerCó
Postman / BrunoTest APICó
VS CodeEditor với FHIR extensionsCó
Node.jsChạy SUSHI (FHIR Shorthand compiler)Khuyến nghị
Java 17+HAPI FHIR Client libraryTùy chọn

2. Cài đặt HAPI FHIR Server với Docker

HAPI FHIR là FHIR Server mã nguồn mở phổ biến nhất, được viết bằng Java. Cách nhanh nhất để chạy là dùng Docker.

Bước 1: Tạo file docker-compose.yml

version: "3.8"
services:
  hapi-fhir:
    image: hapiproject/hapi:latest
    container_name: hapi-fhir-server
    ports:
      - "8080:8080"
    environment:
      - hapi.fhir.fhir_version=R5
      - hapi.fhir.allow_multiple_delete=true
      - hapi.fhir.allow_external_references=true
      - hapi.fhir.reuse_cached_search_results_millis=-1
    volumes:
      - hapi-data:/data/hapi
    restart: unless-stopped

volumes:
  hapi-data:

Bước 2: Khởi chạy server

# Tạo thư mục dự án
mkdir fhir-lab && cd fhir-lab

# Tạo docker-compose.yml (nội dung ở trên)

# Khởi chạy
docker compose up -d

# Kiểm tra log
docker compose logs -f hapi-fhir

Đợi khoảng 30-60 giây, server sẽ sẵn sàng tại http://localhost:8080.

Bước 3: Kiểm tra server

# Lấy CapabilityStatement
curl -s http://localhost:8080/fhir/metadata | jq '.fhirVersion'
# Kết quả: "5.0.0"

# Kiểm tra resource types được hỗ trợ
curl -s http://localhost:8080/fhir/metadata | jq '.rest[0].resource | length'
# Kết quả: 157 (hoặc gần đó)

HAPI FHIR Web UI

Truy cập http://localhost:8080 để vào HAPI FHIR Web Testing UI — một giao diện web cho phép bạn thực hiện mọi thao tác FHIR mà không cần viết code.

3. FHIR Test Servers công khai

Ngoài local server, bạn có thể dùng các server công khai để test:

ServerURLVersionGhi chú
HAPI FHIR R5https://hapi.fhir.org/baseR5R5Public, free, reset định kỳ
HAPI FHIR R4https://hapi.fhir.org/baseR4R4Public, free
Firely Serverhttps://server.fire.lyR4Sandbox miễn phí
SMART Health IThttps://launch.smarthealthit.orgR4SMART on FHIR sandbox

Lưu ý: Không đưa dữ liệu thật lên public servers. Chỉ dùng dữ liệu test/synthetic.

4. Cấu hình Postman cho FHIR

Bước 1: Tạo Collection

Tạo collection "FHIR Lab" trong Postman với biến:

  • baseUrl = http://localhost:8080/fhir

Bước 2: Tạo các request cơ bản

1. CapabilityStatement (GET metadata)

GET {{baseUrl}}/metadata
Accept: application/fhir+json

2. Create Patient (POST)

POST {{baseUrl}}/Patient
Content-Type: application/fhir+json
Accept: application/fhir+json

{ "resourceType": "Patient", "identifier": [{ "system": "http://fhir.vn/sid/cccd", "value": "001085012345" }], "name": [{ "use": "official", "family": "Nguyễn", "given": ["Văn", "A"] }], "gender": "male", "birthDate": "1985-03-15", "address": [{ "use": "home", "line": ["123 Lê Lợi, Quận 1"], "city": "Thành phố Hồ Chí Minh", "country": "VN" }], "telecom": [{ "system": "phone", "value": "+84901234567", "use": "mobile" }] }

3. Read Patient (GET)

GET {{baseUrl}}/Patient/{{patientId}}
Accept: application/fhir+json

4. Search Patient (GET)

GET {{baseUrl}}/Patient?family=Nguyen&gender=male
Accept: application/fhir+json

5. Update Patient (PUT)

PUT {{baseUrl}}/Patient/{{patientId}}
Content-Type: application/fhir+json
Accept: application/fhir+json

5. VS Code Extensions cho FHIR

Cài đặt các extensions hữu ích:

FHIR Tools (khuyên dùng)

  • FHIR Shorthand (SUSHI/HL7) — syntax highlighting cho FSH

  • REST Client (Huachao Mao) — gửi HTTP requests trực tiếp từ VS Code

  • JSON Path Finder — navigate JSON lớn

Sử dụng REST Client trong VS Code

Tạo file fhir-test.http:

@baseUrl = http://localhost:8080/fhir

### Metadata
GET {{baseUrl}}/metadata
Accept: application/fhir+json

### Create Patient
POST {{baseUrl}}/Patient
Content-Type: application/fhir+json

{
  "resourceType": "Patient",
  "name": [{"family": "Trần", "given": ["Thị", "B"]}],
  "gender": "female",
  "birthDate": "1990-07-20"
}

### Search all patients
GET {{baseUrl}}/Patient?_count=10
Accept: application/fhir+json

Click "Send Request" phía trên mỗi request để gửi.

6. FHIR Shorthand (FSH) và SUSHI

FHIR Shorthand (FSH) là ngôn ngữ đặc tả để viết Profiles, Extensions, ValueSets một cách ngắn gọn. SUSHI là compiler biên dịch FSH thành FHIR resources.

Cài đặt SUSHI

# Cài Node.js (nếu chưa có)
# macOS
brew install node

# Cài SUSHI globally
npm install -g fsh-sushi

# Kiểm tra
sushi --version

Ví dụ FSH đơn giản

Profile: VNPatient
Parent: Patient
Id: vn-patient
Title: "Vietnam Core Patient Profile"
Description: "Profile cho bệnh nhân Việt Nam"

* identifier 1..* MS
* identifier ^slicing.discriminator.type = #pattern
* identifier ^slicing.discriminator.path = "system"
* identifier ^slicing.rules = #open

* identifier contains cccd 0..1 MS
* identifier[cccd].system = "http://fhir.vn/sid/cccd"
* identifier[cccd].value 1..1

* name 1..* MS
* gender 1..1 MS
* birthDate 1..1 MS

FSH sẽ được dùng nhiều trong bài 13 (Profiles) và bài 20 (Implementation Guide).

7. Thực hành: Các thao tác CRUD đầu tiên

Bây giờ, hãy thực hành các thao tác cơ bản trên HAPI FHIR Server.

7.1. Tạo Patient (CREATE)

curl -X POST http://localhost:8080/fhir/Patient \
  -H "Content-Type: application/fhir+json" \
  -d '{
    "resourceType": "Patient",
    "identifier": [{
      "system": "http://fhir.vn/sid/cccd",
      "value": "001085012345"
    }],
    "name": [{
      "use": "official",
      "family": "Nguyễn",
      "given": ["Văn", "A"]
    }],
    "gender": "male",
    "birthDate": "1985-03-15",
    "address": [{
      "line": ["123 Lê Lợi"],
      "city": "Hồ Chí Minh",
      "country": "VN"
    }]
  }'

Server trả về 201 Created với header Location: Patient/{id}/_history/1.

7.2. Đọc Patient (READ)

# Thay {id} bằng id thực tế được trả về
curl -s http://localhost:8080/fhir/Patient/{id} | jq '.name[0]'

7.3. Tìm kiếm Patient (SEARCH)

# Tìm theo họ
curl -s "http://localhost:8080/fhir/Patient?family=Nguyen" | jq '.total'

# Tìm theo giới tính
curl -s "http://localhost:8080/fhir/Patient?gender=male" | jq '.entry | length'

# Tìm theo identifier (số CCCD)
curl -s "http://localhost:8080/fhir/Patient?identifier=http://fhir.vn/sid/cccd|001085012345" | jq '.entry[0].resource.name'

7.4. Cập nhật Patient (UPDATE)

curl -X PUT http://localhost:8080/fhir/Patient/{id} \
  -H "Content-Type: application/fhir+json" \
  -d '{
    "resourceType": "Patient",
    "id": "{id}",
    "identifier": [{
      "system": "http://fhir.vn/sid/cccd",
      "value": "001085012345"
    }],
    "name": [{
      "use": "official",
      "family": "Nguyễn",
      "given": ["Văn", "A"]
    }],
    "gender": "male",
    "birthDate": "1985-03-15",
    "telecom": [{
      "system": "phone",
      "value": "+84901234567",
      "use": "mobile"
    }],
    "address": [{
      "line": ["456 Nguyễn Huệ"],
      "city": "Hồ Chí Minh",
      "country": "VN"
    }]
  }'

7.5. Xóa Patient (DELETE)

curl -X DELETE http://localhost:8080/fhir/Patient/{id}
# Trả về 200 OK hoặc 204 No Content

7.6. Xem lịch sử (HISTORY)

# Lịch sử một resource cụ thể
curl -s http://localhost:8080/fhir/Patient/{id}/_history | jq '.entry | length'

# Lịch sử toàn bộ Patient type
curl -s "http://localhost:8080/fhir/Patient/_history?_count=5" | jq '.entry[].request.method'

8. Tạo dữ liệu test hàng loạt

Để có dữ liệu thực hành phong phú, sử dụng Synthea — công cụ tạo dữ liệu bệnh nhân synthetic:

# Cài Synthea (cần Java 11+)
git clone https://github.com/synthetichealth/synthea.git
cd synthea

# Tạo 10 bệnh nhân
./run_synthea -p 10 --exporter.fhir.export=true

# Output sẽ nằm trong output/fhir/
ls output/fhir/

Các file output là FHIR Bundle (transaction), có thể POST trực tiếp lên server:

# Upload một bundle lên server
curl -X POST http://localhost:8080/fhir \
  -H "Content-Type: application/fhir+json" \
  -d @output/fhir/hospitalInformation1234.json

9. Cấu trúc dự án khuyến nghị

fhir-lab/
├── docker-compose.yml          # HAPI FHIR Server
├── http/                       # REST Client files
│   ├── patient.http
│   ├── observation.http
│   └── search.http
├── fsh/                        # FHIR Shorthand files
│   ├── input/
│   │   └── fsh/
│   │       ├── profiles/
│   │       ├── extensions/
│   │       └── valuesets/
│   └── sushi-config.yaml
├── sample-data/                # Dữ liệu mẫu
│   ├── patients/
│   ├── observations/
│   └── bundles/
└── scripts/                    # Scripts tiện ích
    ├── load-data.sh
    └── cleanup.sh

10. Tóm tắt

Trong bài này, chúng ta đã:

  • Cài đặt HAPI FHIR Server bằng Docker (port 8080)

  • Biết các FHIR Test Servers công khai (hapi.fhir.org)

  • Cấu hình Postman và VS Code REST Client cho FHIR

  • Cài đặt SUSHI (FHIR Shorthand compiler)

  • Thực hành CRUD operations: Create, Read, Search, Update, Delete, History

  • Sử dụng Synthea để tạo dữ liệu test synthetic

Bài tiếp theo, chúng ta sẽ bắt đầu đi sâu vào FHIR Resources — bắt đầu với Patient, Practitioner, Organization và các Resources hành chính.