Back to Guides
Interoperability
Healthcare Data Exchange Standard

HL7 FHIR Guide

Fast Healthcare Interoperability Resources (FHIR) is the modern standard for healthcare data exchange. This guide covers FHIR resources, database schema design, and API implementation.

What is HL7 FHIR?

HL7 FHIR (Fast Healthcare Interoperability Resources) is a next-generation standard framework created by HL7 for exchanging healthcare information electronically. FHIR combines the best features of HL7 v2, HL7 v3, and CDA, while leveraging modern web technologies like RESTful APIs, JSON, and XML.

FHIR organizes healthcare data into modular components called "resources" such as Patient, Observation, Medication, and Encounter. Each resource has a standardized structure and can be used independently or combined to represent complex clinical scenarios.

Core FHIR Resources

Patient Resource

Demographic and administrative information about an individual receiving care.

{
  "resourceType": "Patient",
  "id": "example",
  "identifier": [{
    "use": "official",
    "system": "http://hospital.org/mrn",
    "value": "12345"
  }],
  "name": [{
    "use": "official",
    "family": "Smith",
    "given": ["John", "Robert"]
  }],
  "gender": "male",
  "birthDate": "1974-12-25",
  "address": [{
    "use": "home",
    "line": ["123 Main St"],
    "city": "Anytown",
    "state": "CA",
    "postalCode": "12345"
  }]
}

Observation Resource

Measurements and assertions about a patient - vital signs, lab results, clinical findings.

{
  "resourceType": "Observation",
  "id": "blood-pressure",
  "status": "final",
  "category": [{
    "coding": [{
      "system": "http://terminology.hl7.org/CodeSystem/observation-category",
      "code": "vital-signs"
    }]
  }],
  "code": {
    "coding": [{
      "system": "http://loinc.org",
      "code": "85354-9",
      "display": "Blood pressure panel"
    }]
  },
  "subject": {
    "reference": "Patient/example"
  },
  "effectiveDateTime": "2024-03-30",
  "component": [{
    "code": {
      "coding": [{
        "system": "http://loinc.org",
        "code": "8480-6",
        "display": "Systolic blood pressure"
      }]
    },
    "valueQuantity": {
      "value": 120,
      "unit": "mmHg"
    }
  }]
}

FHIR Database Schema

Recommended PostgreSQL schema for storing FHIR resources with JSONB for flexible resource storage:

-- FHIR Resource Storage Table
CREATE TABLE fhir_resource (
  id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  resource_type       VARCHAR(100) NOT NULL,           -- Patient, Observation, etc.
  resource_id         VARCHAR(255) NOT NULL,           -- FHIR resource ID
  version_id          VARCHAR(100) NOT NULL,           -- Resource version
  last_updated        TIMESTAMP NOT NULL DEFAULT NOW(),
  
  -- JSON storage
  resource_json       JSONB NOT NULL,                  -- Full FHIR resource
  
  -- Search parameters (indexed)
  patient_id          VARCHAR(255),                    -- Reference to patient
  status              VARCHAR(50),                     -- Resource status
  category            VARCHAR(100),                    -- Resource category
  code                VARCHAR(100),                    -- Primary code (LOINC, SNOMED, etc.)
  
  -- Metadata
  created_at          TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at          TIMESTAMP NOT NULL DEFAULT NOW(),
  deleted_at          TIMESTAMP,                       -- Soft delete
  
  UNIQUE(resource_type, resource_id, version_id)
);

-- Indexes for common searches
CREATE INDEX idx_fhir_resource_type ON fhir_resource(resource_type);
CREATE INDEX idx_fhir_patient_id ON fhir_resource(patient_id) WHERE patient_id IS NOT NULL;
CREATE INDEX idx_fhir_status ON fhir_resource(status) WHERE status IS NOT NULL;
CREATE INDEX idx_fhir_last_updated ON fhir_resource(last_updated);
CREATE INDEX idx_fhir_resource_json ON fhir_resource USING GIN(resource_json);

-- Patient-specific table for performance
CREATE TABLE fhir_patient (
  id                  UUID PRIMARY KEY,
  resource_id         VARCHAR(255) UNIQUE NOT NULL,
  mrn                 VARCHAR(100),
  family_name         VARCHAR(255),
  given_name          VARCHAR(255),
  birth_date          DATE,
  gender              VARCHAR(20),
  deceased            BOOLEAN DEFAULT FALSE,
  phone               VARCHAR(50),
  email               VARCHAR(255),
  address_city        VARCHAR(100),
  address_state       VARCHAR(2),
  address_zip         VARCHAR(10),
  
  -- Full resource
  resource_json       JSONB NOT NULL,
  
  created_at          TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at          TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_patient_mrn ON fhir_patient(mrn);
CREATE INDEX idx_patient_name ON fhir_patient(family_name, given_name);
CREATE INDEX idx_patient_birth_date ON fhir_patient(birth_date);

FHIR RESTful API

FHIR uses standard HTTP methods for CRUD operations:

GET

Read a Resource

GET /fhir/Patient/12345
GET

Search Resources

GET /fhir/Patient?family=Smith&birthdate=1974-12-25GET /fhir/Observation?patient=12345&code=8480-6
POST

Create a Resource

POST /fhir/Patient

Body: JSON FHIR Patient resource

PUT

Update a Resource

PUT /fhir/Patient/12345

Implementation Best Practices

Use SMART on FHIR for Authorization

Implement OAuth 2.0 and OpenID Connect for secure access to FHIR resources.

Version Your Resources

Always maintain version history for audit trails and data integrity.

Optimize with Bundles

Use FHIR Bundles to batch multiple resources in a single transaction.

Validate Against Profiles

Use US Core or other implementation guides to ensure compliance.

Related Healthcare Standards