Skip to content

GIDSOpenStandaarden/welldata-ephemeral-fhir-service

Repository files navigation

WellData Ephemeral FHIR Service

An ephemeral FHIR R4 service for the WellData project, providing session-scoped in-memory FHIR resource storage with HAPI FHIR.

Overview

The WellData Ephemeral FHIR Service implements the ephemeral FHIR service concept from the WellData Implementation Guide. It provides:

  • Session-scoped storage: Each access token gets its own isolated FHIR resource store
  • Token-bound lifecycle: Sessions are tied to JWT access token expiry
  • In-memory operation: Fast, ephemeral storage for client-side FHIR operations
  • WellData profiles: Serves StructureDefinitions from the WellData Implementation Guide

Current Implementation Status

Feature Status
In-memory FHIR R4 storage Implemented
Session isolation per access token Implemented
JWT token parsing (jti, sub, exp) Implemented
Automatic session cleanup Implemented
WellData IG profile serving Implemented
Solid pod integration Implemented (pod URL derived from WebID)
Static Questionnaire serving Implemented (from local files)
Token signature validation Not yet implemented

Planned Enhancements

The following features are planned for future releases:

  • Questionnaire proxy/federation: Support proxying Questionnaires from a remote FHIR server instead of or in addition to local files
  • Configurable Questionnaire sources: Allow configuration of multiple Questionnaire sources (local, remote, or combined)
  • Questionnaire caching: Cache remote Questionnaires with configurable TTL

Quick Start

Using Docker Compose (Recommended)

Start all services (FHIR server, Solid pod, and demo client):

docker compose up --build

For development with auto-rebuild on file changes:

docker compose watch

Services will be available at:

Using Maven (FHIR server only)

./mvnw spring-boot:run

The FHIR server will be available at http://localhost:8080/fhir

Demo Client

The demo client is a React application that demonstrates the WellData workflow:

  1. Login with Solid - Authenticate using Solid OIDC (default: local Solid pod)
  2. Fill out a health questionnaire - Answer questions about vitals, wellbeing, lifestyle
  3. Submit responses - Creates a QuestionnaireResponse and linked Observations (with shared timestamp)
  4. View history - See responses grouped with their related observations

Using an External Solid Provider

The demo client supports connecting to external Solid providers instead of the local pod:

  1. Click "Use different Solid provider" on the login screen
  2. Enter the URL of your Solid provider (e.g., https://solidcommunity.net, https://login.inrupt.com)
  3. Click "Login with Solid"

This allows you to use your existing Solid identity with social login providers (Google, etc.) if your Solid provider supports it.

The demo client uses Solid-OIDC with a dynamically generated Client ID Document served at /clientid.jsonld. This document is automatically configured based on the deployment URL, making it work on any host without configuration changes.

Authentication

The service requires a JWT Bearer token for accessing patient data endpoints. The token is used to scope data to a specific session.

Public Endpoints (no authentication required)

  • GET /fhir/metadata - CapabilityStatement
  • GET /fhir/StructureDefinition - WellData profiles
  • GET /fhir/ImplementationGuide - Implementation guide metadata
  • GET /fhir/Questionnaire - Questionnaires (shared definitions)

Protected Endpoints (Bearer token required)

  • /fhir/Patient
  • /fhir/Observation
  • /fhir/QuestionnaireResponse

Example with Authentication

# Get a JWT token from your identity provider, then:
curl -H "Authorization: Bearer <your-jwt-token>" http://localhost:8080/fhir/Patient

The service extracts the following claims from the JWT:

  • jti - Used as session identifier (falls back to token hash if not present)
  • sub - WebID (e.g., https://roland.solidcommunity.net/profile/card#me) used to derive the Solid pod URL
  • exp - Expiry time (session is cleaned up after this time)

API Examples

Get CapabilityStatement

curl http://localhost:8080/fhir/metadata

Get WellData Profiles

curl http://localhost:8080/fhir/StructureDefinition

Search Patients (requires auth)

curl -H "Authorization: Bearer <token>" http://localhost:8080/fhir/Patient

Search Observations by Patient (requires auth)

curl -H "Authorization: Bearer <token>" \
  "http://localhost:8080/fhir/Observation?subject=Patient/example-welldata-patient"

Create a new Patient (requires auth)

curl -X POST http://localhost:8080/fhir/Patient \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/fhir+json" \
  -d '{"resourceType": "Patient", "name": [{"family": "Test", "given": ["User"]}]}'

Supported Resources

Resource Search Parameters
Patient identifier, name, family, given, birthdate
Observation subject, code, date, status, category
Questionnaire identifier, name, title, status
QuestionnaireResponse subject, questionnaire, status, authored, author
StructureDefinition url, name, type, status
ImplementationGuide url, name, status

Architecture

┌─────────────────┐     ┌─────────────────────────────────────────┐
│   Client App    │────▶│      Ephemeral FHIR Service             │
│                 │◀────│                                         │
└─────────────────┘     │  ┌─────────────────────────────────┐    │
                        │  │  AccessTokenInterceptor         │    │
       JWT Token ──────▶│  │  - Extract Bearer token         │    │
                        │  │  - Decode JWT (jti, sub, exp)   │    │
                        │  │  - Create/retrieve session      │    │
                        │  └─────────────────────────────────┘    │
                        │                  │                      │
                        │                  ▼                      │
                        │  ┌─────────────────────────────────┐    │
                        │  │  SessionManager                 │    │
                        │  │  - Per-token resource stores    │    │
                        │  │  - Automatic cleanup on expiry  │    │
                        │  └─────────────────────────────────┘    │
                        │                  │                      │
                        │                  ▼                      │
                        │  ┌─────────────────────────────────┐    │
                        │  │  WellDataResourceProvider       │    │
                        │  │  - Session-scoped CRUD          │    │
                        │  │  - In-memory storage            │    │
                        │  └─────────────────────────────────┘    │
                        └─────────────────────────────────────────┘

Configuration

Configuration is managed via src/main/resources/application.yaml:

server:
  port: 8080

welldata:
  testdata:
    path: classpath:testdata
  ig:
    url: https://github.com/GIDSOpenStandaarden/welldata-implementation-guide/releases/download/v0.1.1/welldata-0.1.1.tgz

Development

Prerequisites

  • Java 21
  • Maven 3.9+
  • Docker (optional)

Build

./mvnw clean package

Run Tests

./mvnw test

Project Structure

src/main/java/nl/gidsopenstandaarden/welldata/fhir/
├── Application.java                     # Spring Boot entry point
├── config/
│   └── WellDataRestfulServer.java      # HAPI FHIR server configuration
├── context/
│   └── AccessTokenContext.java         # ThreadLocal token context
├── interceptor/
│   └── AccessTokenInterceptor.java     # JWT extraction and session setup
├── provider/
│   ├── WellDataResourceProvider.java   # Base session-scoped provider
│   ├── PatientResourceProvider.java
│   ├── ObservationResourceProvider.java
│   ├── QuestionnaireResourceProvider.java
│   ├── QuestionnaireResponseResourceProvider.java
│   ├── StructureDefinitionResourceProvider.java
│   └── ImplementationGuideResourceProvider.java
└── service/
    ├── JsonDataLoader.java             # Test data loading
    ├── IgPackageLoader.java            # IG package loading
    └── SessionManager.java             # Session lifecycle management

CI/CD

This project includes GitHub Actions workflows for continuous integration and deployment.

Automated Builds

On every push to main/master or on tags starting with v:

  • Builds and tests the FHIR server with Maven
  • Builds Docker images for both FHIR server and demo client
  • Pushes images to GitHub Container Registry (ghcr.io)

Deployment

Deployment to Kubernetes is triggered automatically on pushes to main or version tags. Configure the following in your GitHub repository:

Secrets:

  • KUBECONFIG - Base64-encoded kubeconfig file for cluster access

Variables:

  • KUBERNETES_NAMESPACE - Target namespace (default: default)
  • DEFAULT_SOLID_PROVIDER - Solid provider URL (default: https://solidcommunity.net)
  • INGRESS_ENABLED - Enable ingress (default: false)
  • INGRESS_CLASS - Ingress class name (default: nginx)
  • APP_HOSTNAME - Hostname for ingress (default: welldata.example.com)
  • APP_URL - Full URL for environment link

Kubernetes Deployment

A Helm chart is provided for deploying to Kubernetes clusters.

Quick Start

helm install welldata-ephemeral-fhir ./chart/welldata-ephemeral-fhir-service

With Custom Configuration

helm install welldata-ephemeral-fhir ./chart/welldata-ephemeral-fhir-service \
  --set demoClient.defaultSolidProvider=https://solidcommunity.net \
  --set demoClient.service.type=LoadBalancer

Configuration Options

Parameter Description Default
fhirServer.replicaCount Number of FHIR server replicas 1
fhirServer.image.repository FHIR server image gidsopenstandaarden/welldata-ephemeral-fhir-service
fhirServer.image.tag FHIR server image tag latest
demoClient.enabled Enable demo client true
demoClient.defaultSolidProvider Default Solid provider URL https://solidcommunity.net
demoClient.service.type Demo client service type ClusterIP
demoClient.ingress.enabled Enable ingress for demo client false

See chart/welldata-ephemeral-fhir-service/values.yaml for all available options.

Related Projects

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

About

Welldata Ephemeral FHIR Service

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors 2

  •  
  •