FHIR Server (HAPI FHIR)
Pipeline-Managed Service
This service is deployed and managed by its CI/CD pipeline.
For current deployment status, configurations, and code:
- Repository:
https://repo.local/healthflow/ndp-fhir-server - Technology: HAPI FHIR Server (Java/Spring Boot)
- FHIR Version: R4
Overview
The FHIR Server provides a centralized HL7 FHIR R4 compliant repository for all healthcare data in the NDP platform. It serves as the Single Source of Truth for clinical data and enables international interoperability.
Purpose
- Store all clinical data in FHIR R4 format
- Provide standardized FHIR REST API
- Enable interoperability with EMR/HIS systems
- Support international healthcare standards
- Enable CDS Hooks integration
- Provide FHIR search capabilities
- Support SMART on FHIR apps
Why FHIR?
Healthcare Interoperability Standard: HL7 FHIR (Fast Healthcare Interoperability Resources) is the global standard for healthcare data exchange.
Benefits:
- International Standard: Used worldwide (US, EU, Australia, etc.)
- Modern REST API: JSON/XML, easy to integrate
- Extensive Resource Library: 140+ resource types
- Extensibility: Custom extensions for Egypt-specific needs
- Clinical Decision Support: CDS Hooks integration
- SMART on FHIR: Third-party app platform
Architecture
FHIR Resources Used in NDP
Core Clinical Resources
| FHIR Resource | NDP Usage | Mapped From |
|---|---|---|
| Patient | Patient demographics, identifiers, contact info | Patient Registry |
| Practitioner | Healthcare provider information | HPR Registry |
| PractitionerRole | Provider roles, specialties, locations | HPR Registry |
| Organization | Facilities, pharmacies, clinics | HPR Registry, Pharmacy Registry |
| Location | Physical locations of facilities | Pharmacy Registry |
| MedicationRequest | Electronic prescriptions | Prescription Service |
| Medication | Drug information from formulary | Medicine Directory |
| MedicationDispense | Dispensing events | Dispense Service |
| MedicationStatement | Patient medication history | Multiple sources |
| AllergyIntolerance | Patient allergies | Patient Registry |
| Condition | Chronic conditions, diagnoses | Patient Registry |
| Observation | Labs, vitals (renal function, etc.) | Patient Registry |
| Coverage | Insurance coverage | Insurance Service |
| Claim | Insurance claims | Insurance Service |
| AuditEvent | Access and modification logs | Audit Service |
Supporting Resources
| FHIR Resource | Usage |
|---|---|
| Encounter | Patient visits |
| Procedure | Procedures performed |
| DiagnosticReport | Lab results |
| DocumentReference | Clinical documents |
| Provenance | Data origin and history |
| Consent | Patient consent for data sharing |
FHIR API Endpoints
RESTful Operations
# Patient Operations
GET /fhir/Patient/:id # Read patient
GET /fhir/Patient?identifier=29001010101010 # Search by national ID
POST /fhir/Patient # Create patient
PUT /fhir/Patient/:id # Update patient
GET /fhir/Patient/:id/$everything # Get all patient data
# Prescription (MedicationRequest) Operations
GET /fhir/MedicationRequest/:id
GET /fhir/MedicationRequest?patient=Patient/123
GET /fhir/MedicationRequest?authoredon=ge2026-01-01
POST /fhir/MedicationRequest
PUT /fhir/MedicationRequest/:id
PATCH /fhir/MedicationRequest/:id # Partial update
# Dispensing (MedicationDispense) Operations
GET /fhir/MedicationDispense/:id
GET /fhir/MedicationDispense?prescription=MedicationRequest/456
POST /fhir/MedicationDispense
# Allergy Operations
GET /fhir/AllergyIntolerance?patient=Patient/123
POST /fhir/AllergyIntolerance
# Medication Operations
GET /fhir/Medication/:id
GET /fhir/Medication?code=MED001
# Search All Resources
GET /fhir/:resourceType?_count=50&_page=1
GET /fhir/:resourceType?_lastUpdated=ge2026-01-01Advanced FHIR Search
# Complex Searches
GET /fhir/MedicationRequest?patient=Patient/123&status=active&_include=MedicationRequest:medication
# Chained Searches
GET /fhir/MedicationRequest?patient.identifier=29001010101010
# Reverse Chaining
GET /fhir/Patient?_has:MedicationRequest:patient:status=active
# Full-text Search
GET /fhir/Patient?_content=diabetes
# Date Range Search
GET /fhir/MedicationRequest?authoredon=ge2026-01-01&authoredon=le2026-12-31
# Sorting
GET /fhir/Patient?_sort=-birthdateFHIR Operations
# Validate Resource
POST /fhir/MedicationRequest/$validate
# Patient Everything
GET /fhir/Patient/:id/$everything
# Medication Lookup
GET /fhir/Medication/$lookup?code=MED001
# Concept Lookup
GET /fhir/ValueSet/$expand?url=http://hl7.org/fhir/ValueSet/medication-codesFHIR Resource Examples
MedicationRequest (Prescription)
json
{
"resourceType": "MedicationRequest",
"id": "rx-2026-000001",
"status": "active",
"intent": "order",
"medicationReference": {
"reference": "Medication/med-001",
"display": "Amoxicillin 500mg Capsule"
},
"subject": {
"reference": "Patient/pat-29001010101010",
"display": "Ahmed Mohamed Ali"
},
"authoredOn": "2026-04-12T14:30:00+02:00",
"requester": {
"reference": "Practitioner/prac-12345",
"display": "Dr. Fatima Hassan"
},
"reasonCode": [
{
"coding": [
{
"system": "http://hl7.org/fhir/sid/icd-10",
"code": "J01.9",
"display": "Acute sinusitis, unspecified"
}
]
}
],
"dosageInstruction": [
{
"text": "خذ كبسولة واحدة 3 مرات يومياً لمدة 7 أيام - Take 1 capsule 3 times daily for 7 days",
"timing": {
"repeat": {
"frequency": 3,
"period": 1,
"periodUnit": "d",
"duration": 7,
"durationUnit": "d"
}
},
"route": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "26643006",
"display": "Oral route"
}
]
},
"doseAndRate": [
{
"doseQuantity": {
"value": 1,
"unit": "capsule",
"system": "http://unitsofmeasure.org",
"code": "{capsule}"
}
}
]
}
],
"dispenseRequest": {
"validityPeriod": {
"start": "2026-04-12",
"end": "2026-05-12"
},
"quantity": {
"value": 21,
"unit": "capsules"
},
"expectedSupplyDuration": {
"value": 7,
"unit": "days"
}
}
}Patient Resource
json
{
"resourceType": "Patient",
"id": "pat-29001010101010",
"identifier": [
{
"use": "official",
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "NI",
"display": "National Identifier"
}
]
},
"system": "http://egypt.gov.eg/national-id",
"value": "29001010101010"
}
],
"active": true,
"name": [
{
"use": "official",
"family": "Ali",
"given": ["Ahmed", "Mohamed"]
},
{
"use": "official",
"family": "علي",
"given": ["أحمد", "محمد"],
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/language",
"valueCode": "ar"
}
]
}
],
"telecom": [
{
"system": "phone",
"value": "+20 10 1234 5678",
"use": "mobile"
},
{
"system": "email",
"value": "ahmed.ali@example.eg"
}
],
"gender": "male",
"birthDate": "1990-01-01",
"address": [
{
"use": "home",
"type": "physical",
"text": "123 شارع الهرم، الجيزة، مصر",
"line": ["123 Haram Street"],
"city": "Giza",
"district": "Dokki",
"state": "Giza Governorate",
"postalCode": "12311",
"country": "EG"
}
],
"extension": [
{
"url": "http://ndp.egypt.gov.eg/fhir/StructureDefinition/insurance-coverage",
"valueReference": {
"reference": "Coverage/cov-uhis-123456"
}
}
]
}CDS Hooks Integration
FHIR Server supports CDS Hooks for real-time clinical decision support:
yaml
# Hook: order-select (when prescriber adds medication)
POST /fhir/cds-services/prescription-check
{
"hook": "order-select",
"hookInstance": "uuid-123",
"context": {
"userId": "Practitioner/prac-12345",
"patientId": "Patient/pat-29001010101010",
"selections": ["MedicationRequest/draft-rx-001"]
}
}
Response:
{
"cards": [
{
"summary": "Drug-Allergy Interaction",
"indicator": "critical",
"detail": "Patient has documented allergy to Penicillin. Amoxicillin is contraindicated.",
"source": {
"label": "NDP CDSS",
"url": "https://cdss.ndp.eg"
},
"suggestions": [{
"label": "Use alternative antibiotic",
"actions": [{
"type": "delete",
"description": "Remove Amoxicillin"
}, {
"type": "create",
"description": "Prescribe Azithromycin",
"resource": {
"resourceType": "MedicationRequest",
"medicationReference": {
"reference": "Medication/azithromycin-500mg"
}
}
}]
}]
}
]
}FHIR Subscriptions
Real-time notifications for resource changes:
json
{
"resourceType": "Subscription",
"status": "active",
"criteria": "MedicationRequest?status=active&patient=Patient/123",
"channel": {
"type": "rest-hook",
"endpoint": "https://notification-service.ndp.eg/webhook",
"payload": "application/fhir+json"
}
}SMART on FHIR Support
Enable third-party applications:
# OAuth 2.0 / OpenID Connect
GET /fhir/.well-known/smart-configuration
GET /fhir/metadata # Capability Statement
# Authorization Endpoints
GET /auth/authorize
POST /auth/token
# SMART Scopes
patient/Patient.read
patient/MedicationRequest.read
patient/MedicationRequest.write
user/Practitioner.readPerformance & Scalability
Resource Requirements
yaml
resources:
limits:
cpu: "4"
memory: 8Gi
requests:
cpu: "2"
memory: 4Gi
replicas: 5 # For 100M population
autoscaling:
minReplicas: 5
maxReplicas: 20
targetCPUUtilization: 70Performance Targets
| Metric | Target |
|---|---|
| Read Operations (p95) | < 100ms |
| Write Operations (p95) | < 200ms |
| Search Operations (p95) | < 500ms |
| Throughput | 10,000 req/s |
| Database Size | 5-10 TB (estimated) |
Optimization Strategies
- Database Indexing: All search parameters indexed
- Caching: Redis for frequently accessed resources
- Read Replicas: For read-heavy operations
- Partitioning: By resource type and date
- Lucene Search: Full-text search optimization
Security & Compliance
Access Control
yaml
# OAuth 2.0 Scopes
Scopes:
- patient/*.read: Read patient's own data
- patient/*.write: Write patient's own data
- user/*.read: Read as healthcare provider
- user/*.write: Write as healthcare provider
- system/*.read: System-level read (backend services)
- system/*.write: System-level write (backend services)Audit Logging
All FHIR operations generate AuditEvent resources:
json
{
"resourceType": "AuditEvent",
"type": {
"system": "http://dicom.nema.org/resources/ontology/DCM",
"code": "110110",
"display": "Patient Record"
},
"action": "R",
"recorded": "2026-04-12T14:30:00+02:00",
"agent": [
{
"who": {
"reference": "Practitioner/prac-12345"
},
"requestor": true
}
],
"source": {
"observer": {
"reference": "Device/fhir-server-01"
}
},
"entity": [
{
"what": {
"reference": "Patient/pat-29001010101010"
}
}
]
}Configuration
Environment Variables
yaml
# HAPI FHIR Configuration
HAPI_FHIR_VERSION: R4
HAPI_FHIR_SERVER_ADDRESS: https://fhir.ndp.eg/fhir
# Database
DATABASE_URL: postgresql://user:pass@postgresql.data-stack:5432/fhir
DATABASE_POOL_SIZE: 50
# Performance
SUBSCRIPTION_ENABLED: true
BULK_EXPORT_ENABLED: true
REUSE_CACHED_SEARCH_RESULTS: true
ENABLE_INDEX_MISSING_FIELDS: true
# Security
CORS_ENABLED: true
OAUTH_ENABLED: true
OAUTH_ISSUER_URL: https://auth.ndp.eg
# Validation
VALIDATION_ENABLED: true
VALIDATION_STRICT: true
UPLOAD_EXTERNAL_CODE_SYSTEMS: true
# Search
LUCENE_ENABLED: true
MAX_PAGE_SIZE: 500
DEFAULT_PAGE_SIZE: 20Related Services
- Prescription Service - Creates MedicationRequest resources
- Dispense Service - Creates MedicationDispense resources
- Patient Registry - Creates Patient resources
- HPR Registry - Creates Practitioner resources
- Clinical Decision Support - Consumes FHIR resources for validation
Support
For FHIR server issues:
- HAPI FHIR Documentation: https://hapifhir.io
- HL7 FHIR Specification: https://hl7.org/fhir/R4/
- Repository Issues: internal issue tracker
- Slack: #fhir-server