Bulk Operations
Ignixa supports FHIR Bulk Data Access specification for high-volume data exchange.
See Operations for API reference and spec links.
$export
System Export
Export all data from the server (single-tenant mode):
POST /$export
Accept: application/fhir+json
Prefer: respond-async
Or with explicit tenant:
POST /tenant/{tenantId}/$export
Accept: application/fhir+json
Prefer: respond-async
Patient Export
Export all Patient compartment data:
POST /tenant/{tenantId}/Patient/$export
Accept: application/fhir+json
Prefer: respond-async
Group Export
Export data for a specific group of patients:
POST /tenant/{tenantId}/Group/{group-id}/$export
Accept: application/fhir+json
Prefer: respond-async
Export Parameters
| Parameter | Description | Example |
|---|---|---|
_outputFormat | Output format | application/fhir+ndjson, application/vnd.apache.parquet |
_since | Only resources modified since | 2024-01-01T00:00:00Z |
_type | Resource types to export | Patient,Observation |
_typeFilter | Search filters per type | Patient?active=true |
_elements | Elements to include | id,meta,identifier |
_viewDefinition | SQL on FHIR ViewDefinition ID (required for Parquet) | patient-demographics |
Example with Parameters
# Standard NDJSON export
GET /$export?_type=Patient,Observation&_since=2024-01-01T00:00:00Z&_outputFormat=application/fhir+ndjson
Parquet Export (SQL on FHIR)
Export FHIR data directly to Apache Parquet format using SQL on FHIR v2 ViewDefinitions. This enables direct analytics integration with tools like Spark, Databricks, and Snowflake.
Creating a ViewDefinition
First, create a ViewDefinition resource that defines the tabular projection:
POST /ViewDefinition
Content-Type: application/fhir+json
{
"resourceType": "ViewDefinition",
"id": "patient-demographics",
"name": "patient_demographics",
"resource": "Patient",
"select": [
{ "column": [{ "name": "id", "path": "id" }] },
{ "column": [{ "name": "family_name", "path": "name.first().family" }] },
{ "column": [{ "name": "given_name", "path": "name.first().given.first()" }] },
{ "column": [{ "name": "birth_date", "path": "birthDate" }] },
{ "column": [{ "name": "gender", "path": "gender" }] }
]
}
Exporting to Parquet
GET /$export?_type=Patient&_outputFormat=application/vnd.apache.parquet&_viewDefinition=patient-demographics
Accept: application/fhir+json
Prefer: respond-async
Parquet Export Response
{
"transactionTime": "2024-01-15T10:30:00Z",
"request": "/$export?_type=Patient&_outputFormat=application/vnd.apache.parquet&_viewDefinition=patient-demographics",
"requiresAccessToken": false,
"output": [
{
"type": "Patient",
"url": "https://storage.example.org/export/patient_demographics.parquet",
"count": 15420
}
]
}
Benefits of Parquet Export
- Analytics-Ready: Direct integration with Spark, Databricks, Snowflake, BigQuery
- Columnar Storage: Efficient compression and query performance
- Schema Preservation: Strong typing from ViewDefinition
- Reduced Transform: No ETL pipeline needed for analytics
See SQL on FHIR SDK for ViewDefinition authoring details.
Async Response
HTTP/1.1 202 Accepted
Content-Location: /tenant/{tenantId}/_export/{jobId}
Poll Status
Check the status of an export job:
GET /tenant/{tenantId}/_export/{jobId}
In Progress
HTTP/1.1 202 Accepted
X-Progress: Exporting... 45%
Complete
{
"transactionTime": "2024-01-15T10:30:00Z",
"request": "/tenant/{tenantId}/$export?_type=Patient",
"requiresAccessToken": false,
"output": [
{
"type": "Patient",
"url": "https://storage.example.org/export/Patient.ndjson",
"count": 15420
},
{
"type": "Observation",
"url": "https://storage.example.org/export/Observation.ndjson",
"count": 892341
}
]
}
Cancel Export
Cancel a running export job:
DELETE /tenant/{tenantId}/_export/{jobId}
$import
Import bulk data into the server. Imports use the DurableTask framework for reliability and progress tracking.
POST /tenant/{tenantId}/$import
Content-Type: application/fhir+json
Prefer: respond-async
{
"resourceType": "Parameters",
"parameter": [
{
"name": "inputFormat",
"valueCode": "application/fhir+ndjson"
},
{
"name": "inputSource",
"valueUri": "https://storage.example.org/import/"
},
{
"name": "input",
"part": [
{ "name": "type", "valueCode": "Patient" },
{ "name": "url", "valueUri": "https://storage.example.org/import/Patient.ndjson" }
]
},
{
"name": "input",
"part": [
{ "name": "type", "valueCode": "Observation" },
{ "name": "url", "valueUri": "https://storage.example.org/import/Observation.ndjson" }
]
}
]
}
Import Response
HTTP/1.1 202 Accepted
Content-Location: /tenant/{tenantId}/_import/{jobId}
Poll Import Status
GET /tenant/{tenantId}/_import/{jobId}
Cancel Import
DELETE /tenant/{tenantId}/_import/{jobId}
Import Options
| Parameter | Description |
|---|---|
inputFormat | Format of input files |
inputSource | Base URL for input files |
input | Individual file specifications |
storageDetail | Storage configuration |
DurableTask Framework
Bulk operations use the DurableTask framework for reliability:
┌─────────────────┐
│ Export Request │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Orchestrator │ Coordinates export
└────────┬────────┘
│
┌────┴────┐
▼ ▼
┌───────┐ ┌───────┐
│Task 1 │ │Task 2 │ Export by type
└───────┘ └───────┘
│
▼
┌─────────────────┐
│ Completion │ Status update
└─────────────────┘
Benefits
- Durability - Survives process restarts
- Parallelism - Concurrent type processing
- Progress - Real-time status updates
- Checkpointing - Resume from failures
Configuration
Bulk operations use DurableTask framework for orchestration and BlobStorage for file storage. Configure in appsettings.json:
DurableTask Configuration
{
"DurableTask": {
"Provider": "SqlServer",
"SqlServer": {
"TaskHubName": "ignixa"
}
}
}
Providers:
SqlServer- Uses SQL Server (default, integrated with FHIR database)AzureStorage- Uses Azure Storage for distributed scenariosFileSystem- Development/testing only
Blob Storage Configuration
{
"BlobStorage": {
"Provider": "Local",
"RootDirectory": "fhir-exports",
"ContainerName": "fhirstorage"
}
}
Or for Azure:
{
"BlobStorage": {
"Provider": "Azure",
"ContainerName": "fhirstorage",
"StorageAccountUri": "https://yourAccount.blob.core.windows.net",
"UseManagedIdentity": true
}
}
Import Configuration
{
"Import": {
"MaxConcurrentFiles": 1,
"ConsumerCount": 1,
"BatchSize": 100,
"ChannelCapacity": 1000
}
}
Performance Tips
- Use
_type- Export only needed resource types - Use
_since- Incremental exports for efficiency - Use
_elements- Reduce payload size - Monitor progress - Poll status for large exports