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

Lesson 3: Install the FHIR development environment

Install HAPI FHIR Server (Docker), public FHIR Test Server, Postman Collection for FHIR, FHIR Shorthand (FSH) and SUSHI, VS Code extensions for FHIR, test the first CRUD operations.

🏗️ Architecture — Lesson 3 Lesson 3: Install the FHIR development environment

HL7 FHIR - Basic to Advanced Healthcare Data Standard

Part 1: HL7 and FHIR Platform

xdev.asia

1. Overview of necessary tools

To practice FHIR effectively, you need to prepare the following tools:

ToolsPurposeRequired?
HAPI FHIR ServerFHIR Server local for practiceYes
DockerRun HAPI FHIR ServerYes
Postman/BrunoTest APIYes
VS CodeEditor with FHIR extensionsYes
Node.jsRun SUSHI (FHIR Shorthand compiler)Recommended
Java 17+HAPI FHIR Client libraryOptions

2. Install HAPI FHIR Server with Docker

HAPI FHIR is the most popular open source FHIR Server, written in Java. The fastest way to get it running is using Docker.

Step 1: Create docker-compose.yml file

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:

Step 2: Launch the 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

Wait about 30-60 seconds, the server will be ready http://localhost:8080.

Step 3: Check the 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

Access http://localhost:8080 to enter HAPI FHIR Web Testing UI — a web interface that allows you to perform all FHIR operations without writing code.

3. Public FHIR Test Servers

In addition to local servers, you can use public servers to test:

ServerURLVersionNotes
HAPI FHIR R5https://hapi.fhir.org/baseR5R5Public, free, reset periodically
HAPI FHIR R4https://hapi.fhir.org/baseR4R4Public, free
Firely Serverhttps://server.fire.lyR4Sandbox free
SMART Health IThttps://launch.smarthealthit.orgR4SMART on FHIR sandbox

Note: Do not post real data to public servers. Use only test/synthetic data.

4. Configure Postman for FHIR

Step 1: Create Collection

Create collection "FHIR Lab" in Postman with variable:

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

Step 2: Create basic requests

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 for FHIR

Install useful extensions:

FHIR Tools (recommended)

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

  • REST Client (Huachao Mao) — send HTTP requests directly from VS Code

  • JSON Path Finder — navigate large JSON

Using REST Client in VS Code

Create files 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" above each request to send.

6. FHIR Shorthand (FSH) and SUSHI

FHIR Shorthand (FSH) is a specification language to write Profiles, Extensions, ValueSets concisely. SUSHI is a compiler that compiles FSH into FHIR resources.

Install 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

Simple FSH example

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 will be used extensively in lesson 13 (Profiles) and lesson 20 (Implementation Guide).

7. Practice: First CRUD operations

Now, let's practice basic operations on HAPI FHIR Server.

7.1. Create 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 returns 201 Created with header Location: Patient/{id}/_history/1.

7.2. Read 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. Search for Patients (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. Update 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. Delete Patient (DELETE)

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

7.6. View history (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. Create batch test data

For rich practice data, use Synthea — tool to create synthetic patient data:

# 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/

The output files are FHIR Bundle (transaction), which can be POST directly to the 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. Recommended project structure

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. Summary

In this article, we have:

  • Install HAPI FHIR Server using Docker (port 8080)

  • Know the FHIR Test Servers public (hapi.fhir.org)

  • Configuration Postman and VS Code REST Client for FHIR

  • Install SUSHI (FHIR Shorthand compiler)

  • Practice CRUD operations: Create, Read, Search, Update, Delete, History

  • Use Synthea to create synthetic test data

Next article, we will start going deeper FHIR Resources — starting with Patient, Practitioner, Organization and Administrative Resources.