HAPI FHIR Server Setup Guide
Learn how to deploy and configure a HAPI FHIR server for healthcare data interoperability. This guide covers installation, database configuration, basic operations, and FHIR resource management.
Introduction to HAPI FHIR
HAPI FHIR (HL7 Application Programming Interface for Fast Healthcare Interoperability Resources) is an open-source implementation of the FHIR standard in Java. It provides a complete FHIR server that you can deploy and customize for your healthcare data interoperability needs.
What is FHIR?
FHIR (Fast Healthcare Interoperability Resources) is a standard for exchanging healthcare information electronically. It defines a set of "resources" representing granular clinical concepts like patients, observations, medications, and procedures. FHIR resources can be easily transmitted using modern web technologies like REST APIs and JSON.
Why Use HAPI FHIR Server?
- Standards-Compliant: Fully implements FHIR specifications (R4, R5)
- Flexible Storage: Supports multiple database backends
- RESTful API: Standard HTTP methods for CRUD operations
- Search Capabilities: Advanced search and query operations
- Extensible: Custom resources and operations
- Open Source: Free to use and modify under Apache License
Common Use Cases
- Electronic Health Record (EHR) integration
- Healthcare data exchange between systems
- Clinical data repositories
- Research data management
- Mobile health applications backend
- Testing and development of FHIR-based systems
Prerequisites
System Requirements
- Operating System: Linux, Windows, or macOS
- Java: JDK 11 or higher (JDK 17 recommended)
- Database: PostgreSQL 12+, MySQL 8+, or SQL Server 2016+
- Memory: Minimum 2GB RAM (4GB+ recommended)
- Storage: 20GB minimum (depends on data volume)
- Docker (optional): For containerized deployment
Required Knowledge
- Basic understanding of REST APIs
- Familiarity with JSON format
- Basic database concepts
- Understanding of FHIR resources (helpful but not required)
Installation
Method 1: Docker Deployment (Recommended)
The easiest way to get started is using the official Docker image:
Quick Start
# Pull and run HAPI FHIR server
docker run -p 8080:8080 hapiproject/hapi:latest
Access the server at http://localhost:8080
Docker Compose with PostgreSQL
For production use, deploy with a persistent database. Create docker-compose.yml:
version: '3.8'
services:
postgres:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_DB: hapi
POSTGRES_USER: admin
POSTGRES_PASSWORD: changeme
volumes:
- postgres_data:/var/lib/postgresql/data
hapi-fhir:
image: hapiproject/hapi:latest
restart: unless-stopped
ports:
- "8080:8080"
environment:
spring.datasource.url: jdbc:postgresql://postgres:5432/hapi
spring.datasource.username: admin
spring.datasource.password: changeme
spring.datasource.driverClassName: org.postgresql.Driver
spring.jpa.properties.hibernate.dialect: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect
hapi.fhir.fhir_version: R4
depends_on:
- postgres
volumes:
postgres_data:
Start the services:
docker compose up -d
Note: On first startup, HAPI FHIR will create database tables automatically.
This may take a few minutes. Monitor logs with docker compose logs -f hapi-fhir
Method 2: Manual Installation
Step 1: Download HAPI FHIR
Download the latest release from the HAPI FHIR GitHub releases page.
Step 2: Set Up Database
Create a database for HAPI FHIR:
# PostgreSQL example
createdb hapi
createuser hapi_user
psql -c "ALTER USER hapi_user WITH PASSWORD 'secure_password';"
psql -c "GRANT ALL PRIVILEGES ON DATABASE hapi TO hapi_user;"
Step 3: Configure Application
Edit application.yaml in the HAPI FHIR directory:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/hapi
username: hapi_user
password: secure_password
driverClassName: org.postgresql.Driver
hapi:
fhir:
fhir_version: R4
server_address: http://localhost:8080/fhir
Step 4: Start the Server
# Using the included script
./hapi-fhir-cli run-server
# Or using Java directly
java -jar hapi-fhir-jpaserver.war
Configuration
Basic Configuration
Key configuration options in application.yaml:
FHIR Version
hapi:
fhir:
fhir_version: R4 # Options: DSTU2, DSTU3, R4, R5
Server Base URL
hapi:
fhir:
server_address: http://yourdomain.com/fhir
Enable Subscriptions
hapi:
fhir:
subscription:
enabled: true
rest_hook_enabled: true
Configure Search Parameters
hapi:
fhir:
max_page_size: 200
default_page_size: 20
max_binary_size: 10485760 # 10MB
Database Configuration
PostgreSQL
spring:
datasource:
url: jdbc:postgresql://localhost:5432/hapi
username: hapi_user
password: secure_password
jpa:
properties:
hibernate.dialect: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect
MySQL
spring:
datasource:
url: jdbc:mysql://localhost:3306/hapi
username: hapi_user
password: secure_password
jpa:
properties:
hibernate.dialect: ca.uhn.fhir.jpa.model.dialect.HapiFhirMySQLDialect
Performance Tuning
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
jpa:
properties:
hibernate.jdbc.batch_size: 20
hibernate.cache.use_query_cache: false
hibernate.cache.use_second_level_cache: false
Basic FHIR Operations
Creating Resources
Create a Patient resource using HTTP POST:
POST http://localhost:8080/fhir/Patient
Content-Type: application/fhir+json
{
"resourceType": "Patient",
"name": [{
"family": "Smith",
"given": ["John"]
}],
"gender": "male",
"birthDate": "1980-01-01"
}
Using curl:
curl -X POST http://localhost:8080/fhir/Patient \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Patient",
"name": [{"family": "Smith", "given": ["John"]}],
"gender": "male",
"birthDate": "1980-01-01"
}'
Reading Resources
Retrieve a specific resource by ID:
GET http://localhost:8080/fhir/Patient/123
Using curl:
curl http://localhost:8080/fhir/Patient/123
Updating Resources
Update an existing resource using PUT:
PUT http://localhost:8080/fhir/Patient/123
Content-Type: application/fhir+json
{
"resourceType": "Patient",
"id": "123",
"name": [{
"family": "Smith",
"given": ["John", "Michael"]
}],
"gender": "male",
"birthDate": "1980-01-01"
}
Deleting Resources
DELETE http://localhost:8080/fhir/Patient/123
Searching Resources
Search by Name
GET http://localhost:8080/fhir/Patient?name=Smith
Search by Date
GET http://localhost:8080/fhir/Patient?birthdate=1980-01-01
Combined Search
GET http://localhost:8080/fhir/Patient?name=Smith&gender=male
Search with Includes
# Get observations and include the related patient
GET http://localhost:8080/fhir/Observation?_include=Observation:subject
Tip: HAPI FHIR includes a web interface at http://localhost:8080
where you can test operations interactively without writing code.
Security Configuration
Enable Authentication
HAPI FHIR supports multiple authentication methods:
Basic Authentication
hapi:
fhir:
security:
enabled: true
basic_auth:
enabled: true
username: admin
password: changeme
OAuth2/SMART on FHIR
hapi:
fhir:
security:
enabled: true
oauth:
enabled: true
issuer_url: https://your-oauth-server.com
client_id: your_client_id
Enable CORS
For web-based applications:
hapi:
fhir:
cors:
enabled: true
allowed_origins:
- https://yourdomain.com
Rate Limiting
hapi:
fhir:
rate_limiting:
enabled: true
max_requests: 100
time_window_seconds: 60
Warning: Never deploy a FHIR server to production without proper authentication. Healthcare data is sensitive and must be protected. Always use HTTPS in production environments.
Best Practices
Data Management
- Use appropriate FHIR resource types for your data
- Implement proper referencing between resources
- Use standard code systems (LOINC, SNOMED CT) for clinical concepts
- Validate resources before submission using FHIR validators
- Implement proper error handling in client applications
Performance
- Use database indexing for frequently searched fields
- Implement pagination for large result sets
- Consider caching for frequently accessed resources
- Monitor database query performance
- Use bulk operations for large data imports
Security
- Always use HTTPS in production
- Implement proper authentication and authorization
- Use audit logging for compliance
- Regularly update HAPI FHIR to get security patches
- Follow HIPAA guidelines if handling US patient data
Backup and Recovery
- Regularly backup your FHIR database
- Test restore procedures periodically
- Document your backup strategy
- Consider replication for high availability
Troubleshooting
Server Won't Start
Check the logs for error messages:
# Docker
docker compose logs hapi-fhir
# Standalone
tail -f logs/hapi-fhir.log
Common issues:
- Database connection errors: Verify database credentials
- Port already in use: Change the port in configuration
- Memory errors: Increase Java heap size
Slow Performance
If the server is slow:
- Check database query performance
- Review database indexes
- Increase database connection pool size
- Add more server resources (CPU, RAM)
Validation Errors
If resources fail validation:
- Check the resource structure against FHIR specifications
- Verify required fields are present
- Use a FHIR validator to test resources
- Review error messages for specific issues
Connection Timeouts
For timeout issues:
spring:
datasource:
hikari:
connection-timeout: 30000
maximum-pool-size: 20
Getting Help
For additional support: