| Crates.io | tlq-fhir-registry-client |
| lib.rs | tlq-fhir-registry-client |
| version | 0.1.10 |
| created_at | 2026-01-05 16:59:08.123031+00 |
| updated_at | 2026-01-10 13:00:31.345854+00 |
| description | FHIR package registry client for loading and caching FHIR packages |
| homepage | https://thalamiq.io |
| repository | https://github.com/thalamiq/tlq-fhir-core |
| max_upload_size | |
| id | 2024246 |
| size | 97,778 |
A Rust client for loading and caching FHIR packages from local cache and the Simplifier package registry.
.fhir/packages directoryuse tlq_fhir_registry_client::RegistryClient;
let client = RegistryClient::new(None);
let package = client.load_package("hl7.fhir.r5.core", "5.0.0")?;
use tlq_fhir_registry_client::{RegistryClient, SimplifierSearchParams};
let client = RegistryClient::new(None);
let params = SimplifierSearchParams {
name: Some("hl7.fhir".to_string()),
fhir_version: Some("4.0.1".to_string()),
..Default::default()
};
let results = client.search_packages(¶ms)?;
for result in results {
println!("{} v{}", result.name, result.version);
}
use tlq_fhir_registry_client::RegistryClient;
let client = RegistryClient::new(None);
// Download and cache a package
let package = client.download_package("hl7.fhir.r4.core", "4.0.1")?;
// Or load from cache if available, download if not
let package = client.load_or_download_package("hl7.fhir.r4.core", "4.0.1")?;
use tlq_fhir_registry_client::RegistryClient;
let client = RegistryClient::new(None);
let versions = client.get_package_versions("hl7.fhir.r4.core")?;
for version in versions {
println!("Available: {}", version);
}
The registry-client crate provides a flexible, extensible system for loading and caching FHIR packages. It supports multiple cache backends through a trait-based architecture and integrates with the Simplifier package registry.
┌─────────────────────────────────────────────────────────────┐
│ RegistryClient<C> │
│ (Generic over PackageCache trait) │
│ │
│ ┌────────────────┐ ┌──────────────────────┐ │
│ │ Cache │ │ Simplifier Client │ │
│ │ (via trait C) │ │ (Optional) │ │
│ └────────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────────┐
│ PackageCache Trait │ │ Simplifier Registry API │
└──────────────────────┘ └──────────────────────────┘
│
│ Implementations
▼
┌──────────────────────┐ ┌──────────────────────────┐
│ FileSystemCache │ │ Custom Implementations │
│ (Default) │ │ - InMemoryCache │
└──────────────────────┘ │ - DatabaseCache │
│ - RedisCache │
│ - S3Cache │
│ - HybridCache │
└──────────────────────────┘
The core abstraction that allows different cache backends:
pub trait PackageCache: Send + Sync {
fn has_package(&self, name: &str, version: &str) -> bool;
fn get_package(&self, name: &str, version: &str) -> Result<CachedPackage>;
fn store_package(&self, package: &FhirPackage) -> Result<()>;
fn list_packages(&self) -> Vec<(String, String)>;
}
Design Decisions:
Send + Sync bounds allow thread-safe usageResult for error handlingDefault implementation that stores packages in ~/.fhir/packages:
pub struct FileSystemCache {
cache_root: PathBuf,
}
Features:
{name}#{version}/package/Generic client that works with any cache implementation:
pub struct RegistryClient<C: PackageCache> {
cache: Arc<C>,
simplifier: Option<SimplifierClient>,
}
Design Decisions:
C: PackageCache for flexibilityArc<C> for cheap cloning and shared ownershipHandles interaction with the Simplifier package registry:
pub struct SimplifierClient {
client: reqwest::Client,
base_url: String,
}
Features:
let client = RegistryClient::new(None);
let package = client.load_package("hl7.fhir.r4.core", "4.0.1")?;
let client = RegistryClient::new(Some(PathBuf::from("/custom/path")));
let cache = MyDatabaseCache::new(connection_string);
let client = RegistryClient::with_cache(cache);
let client = RegistryClient::cache_only(None);
// Only loads from local cache, never hits network
// Try cache first, download if not found
let package = client.load_or_download_package("hl7.fhir.r4.core", "4.0.1")?;
All components are designed for concurrent use:
PackageCache trait requires Send + SyncRegistryClient wraps cache in Arc<C>Errors follow Rust best practices:
pub enum Error {
PackageNotFound { name: String, version: String },
Http(reqwest::Error),
Io(std::io::Error),
Json(serde_json::Error),
// ... other variants
}
All operations return Result<T, Error> for explicit error handling.
CachedPackage pre-builds indices for fast lookupsArc<C>The Simplifier integration supports the following API endpoints:
https://packages.simplifier.net/catalog?<parameters>
Parameters:
name - Package name (can match any part)canonical - Canonical URL for a resource (exact match)fhirversion - FHIR version filterprerelease - Include unreleased packages (boolean)https://packages.simplifier.net/<package-name>
Returns a list of all available versions for a package.
https://packages.simplifier.net/<package-name>/<version>
Downloads a package as a tarball.
Run the Simplifier demo:
cargo run --example simplifier_demo
If you want to disable remote registry access:
use tlq_fhir_registry_client::RegistryClient;
let client = RegistryClient::cache_only(None);
// This client will only load from local cache
The PackageCache trait allows you to implement custom cache backends:
use fhir_package::FhirPackage;
use tlq_fhir_registry_client::{PackageCache, RegistryClient, Result};
use std::collections::HashMap;
use std::sync::RwLock;
struct InMemoryCache {
packages: RwLock<HashMap<String, FhirPackage>>,
}
impl PackageCache for InMemoryCache {
fn has_package(&self, name: &str, version: &str) -> bool {
// Implementation
}
fn get_package(&self, name: &str, version: &str) -> Result<FhirPackage> {
// Implementation
}
fn store_package(&self, package: &FhirPackage) -> Result<()> {
// Implementation
}
fn list_packages(&self) -> Vec<(String, String)> {
// Implementation
}
}
// Use your custom cache
let cache = InMemoryCache::new();
let client = RegistryClient::with_cache(cache);
See examples/custom_cache.rs for a complete implementation.
Store packages in PostgreSQL, MySQL, SQLite:
Distributed caching:
fhir:package:{name}#{version}Cloud-based package storage:
Multi-tier strategy:
Immutable package sets:
Track cache hits/misses and package usage:
Future registries can follow the SimplifierClient pattern:
npm_registry.rs)FhirPackage instancesRegistryClientThe architecture is designed to support additional registries in the future. Each registry will have its own client module similar to simplifier.rs.