FHIR Integration Tutorial
This tutorial will guide you through setting up FHIR integrations using the Healthcare Integration Platform.
Overview
FHIR (Fast Healthcare Interoperability Resources) is a modern standard for exchanging healthcare information. Our platform provides a complete FHIR R4 server implementation that supports:
- FHIR Versions: R4 (4.0.1) - Production Ready
- Resource Types: Patient, Observation, Encounter, Bundle, and core FHIR resources
- Operations: CRUD operations, search, bundles, transactions
- Security: Development mode (authentication can be enabled for production)
- Formats: JSON (primary), XML support
- Standards: Full FHIR R4 specification compliance
Prerequisites
- Healthcare Integration Platform access
- FHIR server endpoint (R4 or R5)
- Network connectivity between systems
- Valid authentication credentials
Step 1: Access the FHIR Server
Platform FHIR Server
The platform includes a built-in FHIR R4 server accessible through the API gateway:
# Access the FHIR server via gateway
base_url="https://your-platform.com/api/v1/fhir"
# Check server capabilities
curl -X GET "$base_url/metadata" \
-H "Accept: application/fhir+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Development vs Production Mode
# Production deployment via gateway
# Authentication required for all requests
curl -X GET "https://your-platform.com/api/v1/fhir/metadata" \
-H "Accept: application/fhir+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# Gateway configuration handles:
# - Authentication and authorization
# - Rate limiting and throttling
# - Request routing to FHIR service
Step 2: Test FHIR Server
Check Server Health
# Check FHIR server health
curl -X GET "https://your-platform.com/api/v1/fhir/health" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_TOKEN"
# Get detailed server information
curl -X GET "https://your-platform.com/api/v1/fhir/info" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_TOKEN"
Expected Response:
{
"status": "success",
"response_time_ms": 150,
"fhir_version": "4.0.1",
"server_info": {
"software": "HAPI FHIR Server",
"version": "6.2.1",
"implementation": {
"description": "Hospital FHIR Server",
"url": "https://fhir.hospital.com"
}
},
"capabilities": {
"resources": ["Patient", "Observation", "Encounter"],
"search_parameters": ["_id", "_lastUpdated", "family", "given"],
"operations": ["read", "create", "update", "search"]
}
}
Step 3: Understanding FHIR Resource Structure
Sample Patient Resource
{
"resourceType": "Patient",
"id": "example-patient",
"meta": {
"versionId": "1",
"lastUpdated": "2025-01-15T10:30:00Z"
},
"identifier": [
{
"use": "usual",
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "MR"
}
]
},
"system": "http://hospital.com/patient-ids",
"value": "123456"
}
],
"active": true,
"name": [
{
"use": "official",
"family": "Doe",
"given": ["John", "Michael"]
}
],
"telecom": [
{
"system": "phone",
"value": "(555) 123-4567",
"use": "home"
},
{
"system": "email",
"value": "john.doe@email.com"
}
],
"gender": "male",
"birthDate": "1985-03-15",
"address": [
{
"use": "home",
"line": ["123 Main Street"],
"city": "Anytown",
"state": "ST",
"postalCode": "12345",
"country": "USA"
}
]
}
Sample Observation Resource
{
"resourceType": "Observation",
"id": "blood-pressure-example",
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
]
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "85354-9",
"display": "Blood pressure panel"
}
]
},
"subject": {
"reference": "Patient/example-patient"
},
"effectiveDateTime": "2025-01-15T10:30:00Z",
"component": [
{
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8480-6",
"display": "Systolic blood pressure"
}
]
},
"valueQuantity": {
"value": 120,
"unit": "mmHg",
"system": "http://unitsofmeasure.org",
"code": "mm[Hg]"
}
},
{
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8462-4",
"display": "Diastolic blood pressure"
}
]
},
"valueQuantity": {
"value": 80,
"unit": "mmHg",
"system": "http://unitsofmeasure.org",
"code": "mm[Hg]"
}
}
]
}
Step 4: Create FHIR Integration
Patient Data Synchronization
curl -X POST "https://your-platform.com/api/v1/integrations" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Patient Data Sync",
"description": "Synchronize patient data between EHR and data warehouse",
"source_connection_id": "fhir-source-conn",
"target_connection_id": "database-target-conn",
"transformation_rules": {
"mappings": {
"patient_id": "$.id",
"medical_record_number": "$.identifier[?(@.type.coding[0].code==\"MR\")].value",
"first_name": "$.name[0].given[0]",
"last_name": "$.name[0].family",
"date_of_birth": "$.birthDate",
"gender": "$.gender",
"phone": "$.telecom[?(@.system==\"phone\")].value",
"email": "$.telecom[?(@.system==\"email\")].value",
"address_line1": "$.address[0].line[0]",
"city": "$.address[0].city",
"state": "$.address[0].state",
"zip_code": "$.address[0].postalCode"
},
"transformations": {
"date_format": "YYYY-MM-DD",
"phone_format": "normalize_phone",
"name_case": "title_case"
}
},
"data_filters": {
"resource_type": "Patient",
"active_only": true,
"exclude_test_patients": true
},
"schedule": "0 */6 * * *",
"batch_size": 100
}'
Observation Data Processing
curl -X POST "https://your-platform.com/api/v1/integrations" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Lab Results Integration",
"description": "Process laboratory observations from FHIR server",
"source_connection_id": "fhir-lab-conn",
"target_connection_id": "analytics-db-conn",
"transformation_rules": {
"mappings": {
"observation_id": "$.id",
"patient_reference": "$.subject.reference",
"test_code": "$.code.coding[0].code",
"test_name": "$.code.coding[0].display",
"result_value": "$.valueQuantity.value",
"result_unit": "$.valueQuantity.unit",
"reference_range_low": "$.referenceRange[0].low.value",
"reference_range_high": "$.referenceRange[0].high.value",
"status": "$.status",
"effective_date": "$.effectiveDateTime",
"performer": "$.performer[0].display"
},
"transformations": {
"extract_patient_id": "extract_id_from_reference($.subject.reference)",
"normalize_units": "standardize_lab_units",
"flag_abnormal": "check_reference_range"
}
},
"data_filters": {
"resource_type": "Observation",
"status": ["final", "amended"],
"category": "laboratory"
},
"schedule": "*/15 * * * *",
"batch_size": 50
}'
Step 5: Advanced FHIR Features
Bundle Processing
# Create a transaction bundle
curl -X POST "https://your-platform.com/api/v1/fhir/fhir" \
-H "Content-Type: application/fhir+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"request": {
"method": "POST",
"url": "Patient"
},
"resource": {
"resourceType": "Patient",
"name": [{
"family": "Doe",
"given": ["John"]
}],
"gender": "male"
}
}
]
}'
FHIR Search and Subscription Integration
curl -X POST "https://your-platform.com/api/v1/integrations" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "FHIR Search Integration",
"description": "Search and sync specific FHIR resources",
"source_connection_id": "fhir-search-conn",
"target_connection_id": "warehouse-conn",
"search_configuration": {
"resource_type": "Patient",
"search_parameters": {
"_lastUpdated": "gt{last_sync_time}",
"active": "true",
"_count": "100",
"_include": "Patient:general-practitioner"
},
"pagination": {
"enabled": true,
"max_pages": 10
}
},
"schedule": "0 */2 * * *"
}'
Step 6: FHIR Resource Validation
Built-in Validation
# Validate a Patient resource
curl -X POST "https://your-platform.com/api/v1/fhir/fhir/Patient/$validate" \
-H "Content-Type: application/fhir+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"resourceType": "Patient",
"id": "test-patient",
"name": [
{
"family": "Doe",
"given": ["John"]
}
],
"gender": "male"
}'
Custom Validation Rules
curl -X POST "https://your-platform.com/api/v1/integrations/{integration_id}" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"validation_rules": {
"required_fields": [
"identifier",
"name",
"gender",
"birthDate"
],
"custom_rules": [
{
"name": "valid_identifier",
"expression": "identifier.exists() and identifier.value.exists()",
"severity": "error"
},
{
"name": "reasonable_birth_date",
"expression": "birthDate <= today() and birthDate >= today() - 150 years",
"severity": "warning"
}
],
"terminology_validation": {
"gender": "http://hl7.org/fhir/ValueSet/administrative-gender",
"marital_status": "http://hl7.org/fhir/ValueSet/marital-status"
}
}
}'
Step 7: Monitoring FHIR Integrations
Get FHIR Server Statistics
# Get server health and statistics
curl -X GET "https://your-platform.com/api/v1/fhir/health" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_TOKEN"
# Get detailed server information
curl -X GET "https://your-platform.com/api/v1/fhir/info" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"total_resources_processed": 5420,
"successful_operations": 5380,
"failed_operations": 40,
"success_rate": 99.26,
"average_processing_time_ms": 180,
"resource_breakdown": {
"Patient": 1200,
"Observation": 3800,
"Encounter": 420
},
"last_execution": "2025-01-15T14:30:00Z",
"next_execution": "2025-01-15T16:30:00Z"
}
FHIR-Specific Health Checks
curl -X GET "https://your-platform.com/api/v1/integrations/{integration_id}/health" \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"status": "healthy",
"fhir_server_status": "operational",
"capability_statement_check": "passed",
"authentication_status": "valid",
"last_successful_operation": "2025-01-15T14:25:00Z",
"error_rate_24h": 0.74,
"avg_response_time_ms": 165,
"resource_availability": {
"Patient": "available",
"Observation": "available",
"Encounter": "available"
}
}
Step 8: Error Handling and Troubleshooting
Common FHIR Integration Issues
Authentication Errors
{
"error": "authentication_failed",
"message": "OAuth token expired",
"resolution": "Refresh OAuth token or check client credentials"
}
Resource Validation Errors
{
"error": "validation_failed",
"message": "Patient resource missing required identifier",
"details": {
"severity": "error",
"expression": "Patient.identifier",
"message": "Patient must have at least one identifier"
}
}
FHIR Server Errors
{
"error": "fhir_server_error",
"http_status": 400,
"fhir_issue": {
"severity": "error",
"code": "invalid",
"details": {
"text": "Invalid resource type 'Patinet' - did you mean 'Patient'?"
}
}
}
Debugging FHIR Integrations
# Enable debug logging for FHIR operations
curl -X PUT "https://your-platform.com/api/v1/integrations/{integration_id}/config" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"debug_mode": true,
"log_requests": true,
"log_responses": true,
"validate_resources": true
}'
Best Practices
Security Considerations
- Development vs Production: Current implementation runs in development mode without authentication
- Production Setup: Enable authentication via
FHIR_REQUIRE_AUTH=true
for production use - Database Security: Use encrypted database connections in production
- Audit Logging: All FHIR operations are logged for compliance tracking
- HTTPS: Always use HTTPS in production deployments
Performance Optimization
- Batch Operations: Use FHIR bundles for multiple resource operations
- Pagination: Implement proper pagination for large datasets
- Caching: Cache frequently accessed resources and metadata
- Connection Pooling: Reuse HTTP connections for better performance
Data Quality
- Validation: Always validate FHIR resources against profiles
- Error Handling: Implement robust error handling and retry logic
- Reference Integrity: Validate resource references
- Terminology: Use standard code systems and value sets
Compliance and Standards
- FHIR Conformance: Follow FHIR specification guidelines
- Implementation Guides: Adhere to relevant FHIR IGs (US Core, etc.)
- Testing: Thoroughly test with FHIR validation tools
- Documentation: Maintain clear integration documentation