|
10 Min. Lesezeit
|

FHIR FUSE: FHIR auf die Unix-Art

Zusammenfassung

FHIR-FUSE ist eine Dateisystem-Schnittstelle für FHIR-Server, die auf FUSE aufbaut und es ermöglicht, mit Gesundheitsdaten mithilfe standardmäßiger Unix-Werkzeuge wie grep, sed und jq zu arbeiten. Keine APIs, keine eigenen Clients – einfach in den FHIR-Server wechseln und loslegen.

Diesen Artikel zusammenfassen mit:
ChatGPTPerplexityClaudeGrok

Seit Jahrzehnten basieren Unix-Systeme auf einer einfachen, aber wirkungsvollen Philosophie: Alles ist eine Datei. Diese Abstraktion ermöglicht es kleinen, fokussierten Werkzeugen, nahtlos zusammenzuarbeiten. Daten verarbeiten? Einen Befehl in den nächsten pipen. grep, sed, jq, diff und andere Standardwerkzeuge nutzen, die Sie bereits kennen.

Was wäre, wenn die Arbeit mit FHIR-Daten demselben Unix-Weg folgen würde? Keine komplexen APIs, keine lästige Authentifizierung, kein eigenes Tooling – nur Ihr bevorzugter Texteditor, Standard-Unix-Befehle und ein Ordner voller FHIR-Ressourcen. FHIR-FUSE bringt diese Unix-Philosophie in die Healthcare-Interoperabilität.

Kurzüberblick

  • FHIR-FUSE bildet Gesundheitsdaten auf Dateisystemkonzepte ab und ermöglicht den Einsatz von Unix-Werkzeugen anstelle von API-Clients
  • Dynamische Erkennung, Lazy Loading und intuitive Abstraktionen erleichtern die FHIR-Erkundung
  • Ideal für Entwicklung, Lernen, Datenanalyse und Migrationen – nicht für hochlastige Produktivsysteme
  • Bringt jahrzehntelange Unix-Kompositionsweisheit in die Healthcare-Interoperabilität

Die Weihnachts-Hackathon-Herausforderung

Jedes Jahr bringt unser Weihnachts-Hackathon Healthcare-Enthusiasten zusammen, um mutige Ideen zu erkunden, die die Grenzen der Gesundheits-IT verschieben. In diesem Jahr stellten wir uns eine provokante Frage: Was wäre, wenn wir die Reibung zwischen Entwicklern und FHIR-Daten beseitigen könnten?

In der Praxis verbringen Healthcare-Entwickler unzählige Stunden damit, API-Clients zu schreiben, Authentifizierung zu verwalten, Paginierung zu handhaben, JSON-Antworten zu parsen und HTTP-Anfragen zu debuggen. Aber was, wenn all das nicht nötig wäre? Was, wenn Sie einfach mit cd in Ihren FHIR-Server wechseln und loslegen könnten?

Das Ergebnis war FHIR-FUSE: eine Dateisystem-Schnittstelle zu FHIR-Servern, die auf FUSE (Filesystem in Userspace) aufbaut. Sie können das vollständig quelloffene Projekt auf GitHub erkunden.

FHIR als Dateisystem neu gedacht

Die Arbeit mit FHIR bedeutet in der Regel APIs, Clients und Request-Logik – doch die Daten selbst haben bereits eine klare Struktur. Die zentrale Erkenntnis hinter FHIR-FUSE ist einfach: FHIR-Ressourcen lassen sich bereits auf natürliche Weise auf Dateisystemkonzepte abbilden.

  • Ressourcentypen (Patient, Observation, Encounter) → Verzeichnisse
  • Einzelne RessourcenJSON-Dateien
  • Ressourcen-IDsDateinamen
  • CRUD-OperationenDateioperationen (erstellen, lesen, aktualisieren, löschen)
  • SuchabfragenSpezielle Verzeichnisse
  • RessourcenhistorieVersteckte Versionsordner
  • OperationenSpezielle Dateien

Dieses gedankliche Modell ist für jeden intuitiv, der jemals mit Dateien gearbeitet hat. Anstatt eine weitere API zu erlernen, nutzen Sie Wissen, das Sie bereits besitzen.

Die Dateisystemstruktur

Wenn Sie einen FHIR-Server mit FHIR-FUSE einbinden, sehen Sie eine virtuelle Dateisystemstruktur wie diese:

./mnt/
├── README.md                          # Documentation
├── Patient/                           # Resource type directory
│   ├── patient-001.json               # Individual resources
│   ├── patient-002.json
│   ├── .patient-001/                  # Hidden history folder
│   │   ├── 1.json                     # Version 1
│   │   ├── 2.json                     # Version 2
│   │   └── 3.json                     # Version 3
│   └── _search/                       # Search directory
│       └── name=Smith/                # Search query
│           └── Patient/
│               └── patient-003.json
├── Observation/
│   ├── observation-001.json
│   └── _search/
└── ViewDefinition/
    ├── patient_demographics.json
    └── $run/                          # Operation directory
        └── patient_demographics.csv   # Operation results

Jedes Verzeichnis und jede Datei in dieser virtuellen Dateisystemstruktur wird dynamisch generiert – basierend auf den Fähigkeiten des FHIR-Servers oder durch vom Benutzer erstellte Dateien und Verzeichnisse.

Designprinzipien

Einen FHIR-Server wie ein Dateisystem zu behandeln klingt in der Theorie einfach, wirft aber praktische Fragen auf. Wie geht man mit verschiedenen Servern, großen Datensätzen und sich verändernden Schemata um? FHIR-FUSE beantwortet diese Fragen durch einige grundlegende Designprinzipien.

1. Dynamische Erkennung

FHIR-FUSE codiert Ressourcentypen nicht fest. Stattdessen fragt es beim Start das CapabilityStatement des Servers ab, um verfügbare Ressourcen zu ermitteln. Das bedeutet, es funktioniert mit jedem FHIR R4-Server direkt – ob Aidbox, HAPI FHIR oder einer eigenen Implementierung.

pub async fn fetch_capability_statement(
    client: &Client,
    fhir_base_url: &str,
) -> anyhow::Result<ServerCapabilities> {
    let url = format!("{}/metadata", fhir_base_url);
    let response = client.get(&url).send().await?;
    let capability_statement: CapabilityStatement = response.json().await?;
    ServerCapabilities::from_capability_statement(capability_statement)
}

Das Dateisystem erstellt automatisch Verzeichnisse für jeden unterstützten Ressourcentyp und macht die Fähigkeiten des Servers sofort sichtbar und erkundbar.

2. Lazy Loading

Healthcare-Datensätze können sehr umfangreich sein. Alle Ressourcen im Voraus zu laden wäre untragbar langsam und speicherintensiv. FHIR-FUSE setzt durchgehend auf Lazy Loading:

  • Verzeichnislistings werden nur abgerufen, wenn Sie ein Verzeichnis mit ls auflisten
  • Ressourceninhalte werden nur geladen, wenn Sie eine Datei lesen
  • Suchergebnisse werden einige Sekunden lang gecacht, um redundante Abfragen zu vermeiden
  • Historienversionen werden bei Bedarf abgerufen, wenn Sie auf die versteckten Ordner zugreifen

Das hält das Dateisystem auch dann reaktionsfähig, wenn mit Servern gearbeitet wird, die Millionen von Ressourcen enthalten.

3. Intuitive Abstraktionen

Die Dateisystem-Schnittstelle bildet FHIR-Konzepte auf vertraute Dateioperationen ab.

Eine Ressource erstellen:

# Create a new patient with basic demographics
echo '{"resourceType":"Patient","name":[{"family":"Smith"}]}' > ./mnt/Patient/new-patient.json

Eine Ressource lesen:

# View a patient record
cat ./mnt/Patient/patient-001.json | jq .

Eine Ressource aktualisieren:

# Edit with your favorite editor
vim ./mnt/Patient/patient-001.json

# Or use jq for programmatic updates
jq '.active = true' ./mnt/Patient/patient-001.json > temp.json
mv temp.json ./mnt/Patient/patient-001.json

Eine Ressource löschen:

# Remove a patient record
rm ./mnt/Patient/patient-001.json

Keine HTTP-Clients, keine Authentifizierungstoken in Ihren Skripten – nur Standard-Unix-Werkzeuge.

4. Suche als Verzeichniserstellung

Eine der elegantesten Designentscheidungen in FHIR-FUSE ist der Umgang mit der FHIR-Suche. Anstatt einer separaten Abfragesprache oder eines Befehls erstellen Sie ein Verzeichnis, dessen Name die Suchparameter enthält:

# Search for female patients named Smith
mkdir -p "./mnt/Patient/_search/name=Smith&gender=female"

# View search results
ls "./mnt/Patient/_search/name=Smith&gender=female/Patient/"
cat "./mnt/Patient/_search/name=Smith&gender=female/Patient/patient-003.json"

Der Verzeichnisname ist die Abfrage. Wenn Sie das Verzeichnis erstellen, führt FHIR-FUSE die Suche aus und befüllt es mit Ergebnissen. Das hat folgende Vorteile:

  • Macht Suchen auffindbar (vergangene Suchen können mit ls eingesehen werden)
  • Ermöglicht Caching von Suchergebnissen (das Verzeichnis bleibt bestehen, bis es gelöscht wird)
  • Unterstützt komplexe Abfragen mit mehreren Parametern
  • Behandelt _include-Parameter auf natürliche Weise (Ergebnisse erscheinen in Unterverzeichnissen nach Ressourcentyp)

5. Operationen als spezielle Verzeichnisse

Operationen sind einer der wichtigsten Bestandteile von FHIR. Einige davon lassen sich als Verzeichnisse im Dateisystem darstellen. Um diese Hypothese zu testen, haben wir versucht, die $run-Operation als Verzeichnis zu implementieren, das ViewDefinition ausführt und die Ergebnisse zurückgibt.

# List available ViewDefinitions
ls ./mnt/ViewDefinition/

# Execute a ViewDefinition
touch "./mnt/ViewDefinition/\$run/patient_demographics.json"

# Read the results
cat "./mnt/ViewDefinition/\$run/patient_demographics.json" | jq .

# Get CSV output
touch "./mnt/ViewDefinition/\$run/patient_demographics.csv"
cat "./mnt/ViewDefinition/\$run/patient_demographics.csv"

Der touch-Befehl löst die Ausführung aus, und das Lesen der Datei liefert die Ergebnisse. Verschiedene Dateiendungen fordern unterschiedliche Ausgabeformate an.

Implementierungseinblicke

Bisher haben wir uns darauf konzentriert, wie sich FHIR-FUSE von außen verhält: wie FHIR-Ressourcen als Dateien erscheinen, wie Suchen als Verzeichnisse funktionieren und wie Standard-Unix-Werkzeuge zur Datenerkundung eingesetzt werden können.

Unter der Haube erfordert diese Abstraktion eine sorgfältige Koordination zwischen Dateisystem-Semantik und den HTTP-basierten APIs von FHIR. Dieser Abschnitt beschreibt die wichtigsten Implementierungsentscheidungen, die FHIR-FUSE reaktionsfähig, vorhersehbar und kompatibel mit verschiedenen FHIR-Servern halten.

Virtuelle Dateisystemarchitektur

FHIR-FUSE basiert auf FUSE (Filesystem in Userspace), das die Implementierung eines Dateisystems vollständig im Userspace ermöglicht, ohne Kernel-Änderungen vorzunehmen. Die Architektur besteht aus mehreren Schlüsselkomponenten:

1. Inode-Index

Jede Datei und jedes Verzeichnis im Dateisystem hat eine eindeutige Inode-Nummer. Wir pflegen einen In-Memory-Index, der Inodes auf virtuelle Dateisystemeinträge abbildet:

pub enum VFSEntry {
    Directory(Directory),             // /Patient
    TextFile(TextFile),               // /README.md
    FHIRResource(FHIRResource),       // /Patient/pt-1.json
    ResourceVersion(ResourceVersion), // /Patient/.pt-1/1.json
    SearchPath(SearchPath),           // /Patient/_search
    SearchQuery(SearchQuery),         // /Patient/_search/gender=female
    SearchResultGroup(SearchResultGroup),
    OperationPath(OperationPath),     // /ViewDefinition/$run
    OperationExecution(OperationExecution),
}

Dieses Enum erfasst alle möglichen Dateisystemeintrag-Typen, jeder mit eigenem Verhalten und eigenen Attributen.

2. Dynamische Verzeichnislistings

Wenn Sie ein Verzeichnis auflisten, generiert FHIR-FUSE das Listing dynamisch basierend auf dem Verzeichnistyp:

  • Stammverzeichnis: Zeigt Ressourcentyp-Verzeichnisse aus dem Capability Statement
  • Ressourcentyp-Verzeichnis: Ruft Ressourcen vom FHIR-Server ab (mit Paginierung)
  • Suchverzeichnis: Zeigt vergangene Suchabfragen
  • Suchabfrage-Verzeichnis: Zeigt Ressourcentyp-Unterverzeichnisse mit Ergebnissen
  • Historienverzeichnis: Zeigt alle Versionen einer bestimmten Ressource

3. Caching-Strategie

Um Reaktionsfähigkeit und Aktualität der Daten in Balance zu halten, implementiert FHIR-FUSE zeitbasiertes Caching:

const TTL: Duration = Duration::from_secs(30);
const CACHE_DURATION: Duration = Duration::from_secs(5);

In der Praxis bedeutet das:

  • Verzeichnislistings werden 5 Sekunden lang gecacht
  • Dateiattribute (Größe, Änderungszeit) haben eine TTL von 30 Sekunden
  • Suchergebnisse werden gecacht, bis sie explizit aktualisiert werden
  • Ressourceninhalte werden beim Lesen stets frisch abgerufen, um Genauigkeit zu gewährleisten

4. Paralleles Ressourcen-Fetching

Beim Laden eines Ressourcentyp-Verzeichnisses ruft FHIR-FUSE mehrere Seiten parallel ab:

pub async fn fetch_resources_parallel(
    client: &Client,
    fhir_base_url: &str,
    resource_type: &str,
) -> anyhow::Result<Vec<Value>> {
    // Discover pagination structure from first page
    let bundle = fetch_first_page(client, fhir_base_url, resource_type).await?;

    // Generate all page URLs
    let page_urls = generate_page_urls(&bundle, MAX_PAGES);

    // Fetch all pages concurrently
    let results = stream::iter(page_urls)
        .map(|url| fetch_page_by_url(&client, &url))
        .buffer_unordered(MAX_CONCURRENT_FETCHES)
        .collect()
        .await;

    // Combine results
    combine_resources(results)
}

Dieser Ansatz verbessert die Performance bei der Arbeit mit großen Datensätzen erheblich, indem bis zu 10 Seiten gleichzeitig abgerufen werden.

Praxisnahe Anwendungsfälle

Die Dateisystem-Schnittstelle erschließt Workflows, die mit herkömmlichen API-Clients schwierig oder umständlich umzusetzen sind. Anstatt eigene Skripte rund um HTTP-Anfragen zu schreiben, können Entwickler Standard-Dateioperationen und Unix-Werkzeuge wiederverwenden, um FHIR-Daten zu verschieben, zu inspizieren, zu versionieren und zu transformieren.

Die nachstehenden Beispiele veranschaulichen, wie dieser Ansatz alltägliche Aufgaben verändert – von einmaligen Migrationen bis hin zu Entwicklung und Debugging.

Datenmigration

# Migrate all patient records from one server to another
cp -r /mnt/source-server/Patient/* /mnt/destination-server/Patient/

Backup und Versionskontrolle

# Create timestamped backup of all observations
tar -czf observations-backup-$(date +%Y%m%d).tar.gz /mnt/fhir/Observation/

# Track patient data changes with git
cd /mnt
git init
git add fhir/Patient/*.json
git commit -m "Initial patient data snapshot"

Datenanalyse mit Standardwerkzeugen

# Count all FHIR resources
find /mnt/fhir -name "*.json" | wc -l

# Extract patient family names and count occurrences
cat /mnt/fhir/Patient/*.json | jq -r '.name[0].family' | sort | uniq -c

# Search for patients with diabetes diagnoses with grep
grep -r "diabetes" /mnt/fhir/Condition/

# Analyze patient demographics (ID, birthDate, gender) with awk
cat /mnt/fhir/Patient/*.json | jq -r '[.id, .birthDate, .gender] | @csv' | \
  awk -F, '{print $3}' | sort | uniq -c

Skripting und Automatisierung

# Activate all patient records with a batch operation
for file in /mnt/fhir/Patient/*.json; do
  jq '.active = true' "$file" > "$file.tmp" && mv "$file.tmp" "$file"
done

# Monitor patient directory for recent changes
watch -n 5 'ls -l /mnt/fhir/Patient/ | tail -10'

# Export patient demographics as CSV
cat /mnt/fhir/Patient/*.json | \
  jq -r '[.name[0].family, .name[0].given[0], .birthDate] | @csv' | \
  csvtool col 1,2,3 - | \
  head -20

Entwicklung und Tests

# Inspect test patient data during development
cat /mnt/fhir/Patient/test-patient-1.json | jq .

# Create reusable test fixtures from FHIR server
cp /mnt/fhir/Patient/example.json ./test/fixtures/

# Validate all patient JSON files for syntax errors
for file in /mnt/fhir/Patient/*.json; do
  jq empty "$file" 2>/dev/null || echo "Invalid JSON: $file"
done

Arbeit mit der Ressourcenhistorie

Eine der mächtigsten Funktionen von FHIR-FUSE ist der Zugriff auf die Ressourcen-Versionshistorie über versteckte Verzeichnisse. Jedes Mal, wenn eine Ressource aktualisiert wird, pflegen FHIR-Server historische Versionen. FHIR-FUSE stellt diese als Dateien in versteckten .resource-id-Ordnern bereit:

# View the current patient record
cat /mnt/fhir/Patient/patient-123.json

# List all historical versions of this patient
ls -la /mnt/fhir/Patient/.patient-123/
# Output:
# 1.json
# 2.json
# 3.json

# View how the patient record looked at version 1
cat /mnt/fhir/Patient/.patient-123/1.json

Versionen mit Standard-diff vergleichen

Sobald Ressourcenversionen als Dateien verfügbar sind, können Sie sofort vertraute Diff-Werkzeuge verwenden, um zu sehen, was sich zwischen Aktualisierungen geändert hat – ohne eigene Skripte zu schreiben oder API-Antworten manuell zusammenzusetzen.

# See what changed between version 1 and version 2
diff /mnt/fhir/Patient/.patient-123/1.json \
     /mnt/fhir/Patient/.patient-123/2.json

# Compare an old version against the current record
diff /mnt/fhir/Patient/.patient-123/2.json \
     /mnt/fhir/Patient/patient-123.json

Difftastic für anschauliche strukturelle Diffs verwenden

Difftastic ist ein strukturelles Diff-Werkzeug, das JSON-Syntax versteht und eine weitaus lesbarere Ausgabe liefert als herkömmliche zeilenbasierte Diffs. Anstatt Zeilen zu vergleichen, hebt es semantische Änderungen hervor und macht Unterschiede leichter nachvollziehbar.

# Install difftastic
brew install difftastic  # macOS
# or: cargo install difftastic

# Compare versions with syntax-aware diffing
difft /mnt/fhir/Patient/.patient-123/1.json \
      /mnt/fhir/Patient/.patient-123/2.json

Beispielausgabe von difftastic:

Patient/patient-123.json
  {
    "resourceType": "Patient",
    "id": "patient-123",
-   "active": false,
+   "active": true,
    "name": [{
      "family": "Smith",
-     "given": ["John"]
+     "given": ["John", "Michael"]
    }],
+   "telecom": [{
+     "system": "phone",
+     "value": "+1-555-0123"
+   }],
    "birthDate": "1980-01-15"
  }

Analyse des Audit-Trails

Da jede Version eine gewöhnliche Datei ist, lässt sich leicht über die gesamte Historie skripten, um Audit-relevante Fragen zu beantworten: wann sich ein Feld geändert hat, wer es aktualisiert hat oder wie sich eine Ressource im Laufe der Zeit entwickelt hat.

# View when each version was last updated
for version in /mnt/fhir/Patient/.patient-123/*.json; do
  echo "=== $version ==="
  jq '.meta.lastUpdated' "$version"
done

# Track when the active status changed for a patient
for version in /mnt/fhir/Patient/.patient-123/*.json; do
  active=$(jq -r '.active' "$version")
  updated=$(jq -r '.meta.lastUpdated' "$version")
  echo "$updated: active=$active"
done

# Create a visual timeline of structural changes with difftastic
v1=/mnt/fhir/Patient/.patient-123/1.json
v2=/mnt/fhir/Patient/.patient-123/2.json
v3=/mnt/fhir/Patient/.patient-123/3.json

echo "Changes from v1 to v2:"
difft "$v1" "$v2"
echo -e "\nChanges from v2 to v3:"
difft "$v2" "$v3"

Das macht das Debuggen von Datenproblemen, das Nachvollziehen der Ressourcenentwicklung und die Compliance-Prüfung erheblich einfacher. Anstatt mehrere API-Aufrufe zum Abrufen der Historie zu tätigen und JSON manuell zu vergleichen, können Sie vertraute Dateisystemwerkzeuge und moderne Diff-Utilities einsetzen.

Herausforderungen und Abwägungen

Die Entwicklung von FHIR-FUSE hat uns wertvolle Lektionen über die Impedanzungleichheit zwischen REST-APIs und Dateisystemen gelehrt. Obwohl die Dateisystemabstraktion leistungsfähig ist, bringt sie inhärente Einschränkungen mit sich. Das Verständnis dieser Abwägungen hilft Ihnen zu entscheiden, ob FHIR-FUSE für Ihren Anwendungsfall geeignet ist.

1. Asynchrone Operationen

Eine der ersten Herausforderungen tritt an der Grenze zwischen Dateisystemen und Netzwerk-APIs auf. Dateisystemoperationen sind traditionell synchron, FHIR-API-Aufrufe hingegen asynchron. Wir verwenden Tokios Runtime, um diese Lücke zu überbrücken:

struct FhirFuse {
    runtime: Arc<Runtime>,
    http_client: Client,
    // ...
}

// Block on async operations in FUSE callbacks
fn read(&mut self, ino: u64, ...) {
    let result = self.runtime.block_on(async {
        fetch_resource(&self.http_client, &self.fhir_base_url, resource_id).await
    });
    // ...
}

Das ist für Entwicklungsworkflows angemessen, bei denen Netzwerklatenz akzeptabel ist. Produktivsysteme mit hohem Durchsatz profitieren von direkten API-Clients mit Connection-Pooling und Batch-Operationen.

2. Paginierung und große Datensätze

Eine weitere praktische Einschränkung ergibt sich aus der Art, wie Dateisysteme mit großen Verzeichnissen umgehen. FHIR-Server haben oft Tausende oder Millionen von Ressourcen. Wir begrenzen Verzeichnislistings standardmäßig auf 1.000 Ressourcen, um das Dateisystem reaktionsfähig zu halten. Bei der Arbeit mit größeren Datensätzen bieten Suchabfragen eine skalierbarere Möglichkeit, Ergebnisse einzugrenzen.

3. Schreib-Semantik

FHIRs bedingte Erstell- und Aktualisierungsoperationen lassen sich nicht perfekt auf Dateisystem-Schreibvorgänge abbilden. FHIR-FUSE verwendet daher pragmatische Semantik:

  • Das Schreiben in eine neue Datei erstellt eine Ressource mit dem Dateinamen als ID
  • Das Schreiben in eine vorhandene Datei aktualisiert diese Ressource
  • Der Server kann ungültige Ressourcen ablehnen, was dazu führt, dass Schreiboperationen fehlschlagen

4. Plattformunterschiede

Schließlich variiert das Dateisystemverhalten je nach Plattform. FUSE verhält sich unter Linux, macOS und anderen Plattformen unterschiedlich. macOS-Nutzer benötigen macFUSE, und die VM-Architektur von Docker Desktop verhindert die Mount-Propagation zum Host. FHIR-FUSE dokumentiert diese Workarounds und bietet sowohl native als auch containerisierte Deployment-Optionen.

Wann FHIR-FUSE NICHT verwendet werden sollte

Obwohl FHIR-FUSE für bestimmte Workflows leistungsfähig ist, sollten seine Einschränkungen klar sein:

Nicht für hochlastige Produktivsysteme

FHIR-FUSE ist nicht für hochlastige Produktivumgebungen ausgelegt. Jede Dateisystemoperation wird in HTTP-Anfragen an den FHIR-Server übersetzt, was Latenz und Overhead verursacht. Für Produktivsysteme, die Tausende gleichzeitiger Anfragen verarbeiten, sollten direkte FHIR-API-Clients oder SDKs verwendet werden, die Connection-Pooling, Request-Batching und ausgefeilte Retry-Logik implementieren können.

Skalierungsgrenzen des Dateisystems

Diese Einschränkung ist nicht auf FHIR-FUSE beschränkt – sie ist jedem dateisystembasierten Ansatz inhärent. Dateisysteme haben Schwierigkeiten mit:

  • Großen Verzeichnislistings: Das Auflisten eines Verzeichnisses mit mehr als 100.000 Dateien ist auf jedem Dateisystem langsam
  • Gleichzeitigen Schreibvorgängen: Mehrere Prozesse, die gleichzeitig schreiben, können zu Konflikten führen
  • Speicherbeschränkungen: Die Pflege von Inode-Indizes für Millionen von Ressourcen verbraucht erheblich Arbeitsspeicher

Wenn Ihr FHIR-Server Millionen von Ressourcen enthält, wird die Dateisystem-Schnittstelle für das Durchsuchen ganzer Ressourcentypen unpraktisch. Suchabfragen helfen, sind aber keine vollständige Lösung.

Wo FHIR-FUSE wirklich glänzt: Lernen und Entwicklung

FHIR-FUSE glänzt wirklich bei Entwicklung, Lernen und Erkundung, wo Benutzerfreundlichkeit und Transparenz wichtiger sind als Durchsatz:

  • FHIR lernen: Einsteiger können die FHIR-Datenstruktur erkunden, ohne API-Clients erlernen zu müssen
  • Entwicklungsworkflows: Testdaten schnell inspizieren, Fixtures erstellen, Integrationen debuggen
  • Prototyping: Schnell mit FHIR-Ressourcen experimentieren, mithilfe vertrauter Werkzeuge
  • Datenanalyse: Ad-hoc-Abfragen und Analysen mit Standard-Unix-Utilities
  • Migrationsskripte: Einmalige Datenmigrationen zwischen Entwicklungs- und Staging-Umgebungen

Für diese Anwendungsfälle überwiegt die Einfachheit und Intuitivität der Dateisystem-Schnittstelle bei Weitem die Performance-Einschränkungen.

Plattformanforderungen

FHIR-FUSE erfordert FUSE (Filesystem in Userspace)-Unterstützung, die je nach Plattform variiert:

Linux: Native Unterstützung. FUSE ist im Kernel integriert und weit verbreitet. Einfach die Pakete fuse3 oder libfuse installieren und loslegen.

macOS: Erfordert macFUSE mit Sicherheitskompromissen. Sie müssen macFUSE installieren, was Folgendes erfordert:

  • Erlauben von Kernel-Erweiterungen von Drittanbietern in den Systemeinstellungen
  • Auf Apple-Silicon-Macs möglicherweise das Deaktivieren einiger System Integrity Protection (SIP)-Funktionen
  • Erteilen zusätzlicher Sicherheitsberechtigungen

Das ist für Entwicklungsmaschinen handhabbar, kann aber mit unternehmensweiten Sicherheitsrichtlinien in Konflikt geraten.

Windows: FUSE ist eine Unix/Linux-Technologie und wird unter Windows nicht nativ unterstützt. Jedoch könnte WSL2 (Windows Subsystem for Linux) funktionieren, da es einen echten Linux-Kernel ausführt. Theoretisch sollte FHIR-FUSE innerhalb von WSL2 mit installiertem FUSE funktionieren. Falls Sie es ausprobieren, lassen Sie es uns wissen!

FreeBSD: Unterstützt. FreeBSD verfügt über native FUSE-Unterstützung über fusefs-libs.

Was wir gelernt haben

Der Hackathon bestätigte unsere Kernhypothese: FHIR-Daten als Dateien zu behandeln ist intuitiv und leistungsfähig. Entwickler verstanden sofort, wie sie mit dem Dateisystem interagieren können, ohne Dokumentation zu lesen. Standard-Unix-Werkzeuge „funktionierten einfach" für gängige Aufgaben.

Noch wichtiger: Wir entdeckten, dass die Dateisystem-Metapher die Struktur von FHIR-Daten auf eine Weise offenbart, wie es API-Dokumentation nicht kann. Das Durchsuchen von Verzeichnissen zeigt, welche Ressourcentypen existieren, welche Ressourcen verfügbar sind und wie sie zusammenhängen – ganz ohne Spezifikationen zu lesen oder API-Aufrufe zu tätigen.

Das Projekt verdeutlichte auch den Wert des Schichtens von Abstraktionen. FUSE stellt die Dateisystem-Schnittstelle bereit, Rust bietet Speichersicherheit und asynchrone Fähigkeiten, und FHIR liefert das Datenmodell. Jede Schicht macht, was sie am besten kann.

Fazit

FHIR-FUSE zeigt, dass Healthcare-Interoperabilität nicht kompliziert sein muss. Indem FHIR-Konzepte auf Dateisystem-Primitive abgebildet werden, nutzen wir Jahrzehnte an Unix-Tooling und Entwickler-Know-how.

Die Dateisystem-Schnittstelle soll FHIR-APIs nicht ersetzen – sie ist ein ergänzendes Werkzeug, das bestimmte Workflows erheblich vereinfacht. Ob Sie Daten migrieren, Ressourcen analysieren, Integrationen debuggen oder einfach einen FHIR-Server erkunden: FHIR-FUSE lässt Sie so arbeiten, wie Sie es bereits kennen.

Manchmal besteht die beste Innovation darin, komplexe Dinge einfach zu machen. Was wäre, wenn Ihr FHIR-Server nur ein Ordner auf Ihrem Computer wäre? Jetzt kann er das sein.

Bereit, FHIR-FUSE auszuprobieren? Das Projekt ist vollständig quelloffen und wartet darauf, erkundet zu werden: GitHub-Repository

Mehr über Aidbox erfahren: Aidbox FHIR-Server

An der Diskussion teilnehmen: Health Samurai Community

Siehe auch: Agenten sind keine Menschen.

Diesen Artikel teilen
Comments
Comments
Sign in
Loading comments...
Subscribe to our blog

Get the latest articles on FHIR, interoperability, and healthcare IT.