Implementation Features
| Feature | Support | Notes |
|---|
| System Operations | ✅ Full | POST [base]/$operation |
| Type Operations | ✅ Full | POST [base]/{type}/$operation |
| Instance Operations | ✅ Full | POST [base]/{type}/{id}/$operation |
| GET Support | ✅ Full | Query parameters converted to Parameters resource |
| POST Support | ✅ Full | JSON/XML Parameters resource in body |
| Parameter Validation | ✅ Full | Based on OperationDefinition resources |
| Content Negotiation | ✅ Full | Supports _format and Accept headers |
| Async Operations | ✅ Full | Job queue integration for long-running operations |
| Operation Registry | ✅ Full | Dynamic loading from OperationDefinition resources |
Endpoints
TLQ FHIR supports operations at three different levels:
| Level | GET | POST | Context |
|---|
| System | /fhir/$operation?params | /fhir/$operation | Server-wide operations |
| Type | /fhir/{type}/$operation?params | /fhir/{type}/$operation | Operations on a resource type |
| Instance | /fhir/{type}/{id}/$operation?params | /fhir/{type}/{id}/$operation | Operations on a specific resource |
Examples:
# System-level operation (GET)
curl "http://localhost:8080/fhir/\$install-package?name=hl7.fhir.us.core&version=6.0.0"
# System-level operation (POST)
curl -X POST "http://localhost:8080/fhir/\$install-package" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{"name": "name", "valueString": "hl7.fhir.us.core"},
{"name": "version", "valueString": "6.0.0"}
]
}'
# Type-level operation
curl -X POST "http://localhost:8080/fhir/ValueSet/\$expand" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{"name": "url", "valueUri": "http://hl7.org/fhir/ValueSet/administrative-gender"}
]
}'
# Instance-level operation
curl -X POST "http://localhost:8080/fhir/Patient/123/\$everything" \
-H "Content-Type: application/fhir+json"
The $ character in URLs must be escaped as \$ in bash/curl commands.
Built-in Operations
TLQ FHIR includes several built-in operations:
Package Management Operations
| Operation | Level | Description |
|---|
$install-package | System | Install FHIR packages from registry |
Terminology Operations
| Operation | Level | Description |
|---|
$expand | Type | Expand a ValueSet |
$lookup | Type | Look up a code in a CodeSystem |
$validate-code | Type | Validate a code against a ValueSet |
$subsumes | Type | Test subsumption between codes |
$translate | Type | Translate codes using ConceptMap |
$closure | Type | Compute closure table for subsumption |
Administrative Operations
| Operation | Level | Description |
|---|
$reindex | System | Rebuild search parameter indexes |
Operation Invocation
GET vs POST
Operations can be invoked using either GET or POST:
- GET: Parameters passed as query string, automatically converted to Parameters resource
- POST: Parameters resource in request body (JSON or XML)
GET example:
curl "http://localhost:8080/fhir/ValueSet/\$expand?url=http://hl7.org/fhir/ValueSet/administrative-gender&count=10"
POST example:
curl -X POST "http://localhost:8080/fhir/ValueSet/\$expand" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{"name": "url", "valueUri": "http://hl7.org/fhir/ValueSet/administrative-gender"},
{"name": "count", "valueInteger": 10}
]
}'
Parameter Conversion
For GET requests, TLQ FHIR automatically converts query parameters to the appropriate FHIR data types:
- Boolean:
true/false (case-insensitive) → valueBoolean
- Integer: Numeric strings →
valueInteger
- Coding:
system|code format → valueCoding
- String: Everything else →
valueString
Parameter Validation
TLQ FHIR validates operation parameters against OperationDefinition resources:
- Required parameters must be present
- Parameter types must match the definition
- Cardinality constraints are enforced
- Unknown parameters are rejected
Operation Examples
Package Installation
Install a FHIR package from the registry:
# Install US Core package
curl -X POST "http://localhost:8080/fhir/\$install-package" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{"name": "name", "valueString": "hl7.fhir.us.core"},
{"name": "version", "valueString": "6.0.0"},
{"name": "include-dependencies", "valueBoolean": true},
{"name": "include-examples", "valueBoolean": false}
]
}'
Response:
{
"resourceType": "Parameters",
"parameter": [
{ "name": "job-id", "valueString": "pkg-install-12345" },
{ "name": "status", "valueString": "accepted" }
]
}
ValueSet Expansion
Expand a ValueSet to get all its codes:
curl -X POST "http://localhost:8080/fhir/ValueSet/\$expand" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{"name": "url", "valueUri": "http://hl7.org/fhir/ValueSet/administrative-gender"},
{"name": "count", "valueInteger": 100},
{"name": "includeDesignations", "valueBoolean": true}
]
}'
Code Validation
Validate a code against a ValueSet:
curl -X POST "http://localhost:8080/fhir/ValueSet/\$validate-code" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{"name": "url", "valueUri": "http://hl7.org/fhir/ValueSet/administrative-gender"},
{"name": "code", "valueCode": "male"},
{"name": "system", "valueUri": "http://hl7.org/fhir/administrative-gender"}
]
}'
Response:
{
"resourceType": "Parameters",
"parameter": [
{ "name": "result", "valueBoolean": true },
{ "name": "display", "valueString": "Male" }
]
}
Search Index Rebuild
Rebuild search parameter indexes:
curl -X POST "http://localhost:8080/fhir/\$reindex" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{"name": "resource-type", "valueString": "Patient"}
]
}'
Custom Operations
Defining Operations
Custom operations are defined using OperationDefinition resources. When you create an OperationDefinition, TLQ FHIR automatically:
- Registers the operation in the operation registry
- Validates the operation context (system/type/instance)
- Enables parameter validation
- Makes the operation available at appropriate endpoints
Example OperationDefinition:
{
"resourceType": "OperationDefinition",
"id": "patient-summary",
"url": "http://example.org/fhir/OperationDefinition/patient-summary",
"name": "PatientSummary",
"code": "summary",
"system": false,
"type": true,
"instance": true,
"resource": ["Patient"],
"parameter": [
{
"name": "include-medications",
"use": "in",
"min": 0,
"max": "1",
"type": "boolean",
"documentation": "Include current medications in summary"
},
{
"name": "summary",
"use": "out",
"min": 1,
"max": "1",
"type": "Bundle",
"documentation": "Patient summary bundle"
}
]
}
Implementing Operations
Custom operation logic is implemented by extending the Operation trait:
#[async_trait]
impl Operation for PatientSummaryOperation {
async fn execute(&self, request: OperationRequest) -> Result<OperationResult> {
// Extract parameters
let include_meds = request.parameters
.get_boolean("include-medications")
.unwrap_or(false);
// Perform operation logic
let summary_bundle = self.generate_summary(include_meds).await?;
// Return result
Ok(OperationResult::Resource(summary_bundle))
}
}
Asynchronous Operations
Long-running operations use the job queue for asynchronous processing:
- Request: Client submits operation request
- Acceptance: Server returns 202 Accepted with job ID
- Polling: Client polls job status using admin endpoints
- Completion: Job completes with success/failure status
Example async operation flow:
# 1. Submit operation
curl -X POST "http://localhost:8080/fhir/\$install-package" \
-H "Content-Type: application/fhir+json" \
-d '{"resourceType": "Parameters", "parameter": [...]}'
# Response: {"parameter": [{"name": "job-id", "valueString": "pkg-123"}]}
# 2. Check job status
curl "http://localhost:8080/admin/jobs/pkg-123"
# 3. Get results when complete
curl "http://localhost:8080/admin/jobs/pkg-123/result"
Configuration
Operations can be disabled in the server configuration:
fhir:
interactions:
operations:
system: true # Enable system-level operations
type_level: true # Enable type-level operations
instance: true # Enable instance-level operations
Error Handling
Operation errors follow FHIR OperationOutcome patterns:
# Unknown operation
curl -X POST "http://localhost:8080/fhir/\$unknown-operation"
# Returns: 404 Not Found with OperationOutcome
# Invalid parameters
curl -X POST "http://localhost:8080/fhir/\$expand" \
-d '{"resourceType": "Parameters", "parameter": []}'
# Returns: 400 Bad Request - Missing required parameter 'url'
# Wrong context
curl -X POST "http://localhost:8080/fhir/Patient/123/\$expand"
# Returns: 400 Bad Request - Operation 'expand' not available at instance level
- Parameter Validation: Cached OperationDefinition metadata for fast validation
- Content Negotiation: Efficient format conversion using shared formatters
- Async Processing: Long operations don’t block HTTP threads
- Resource Cleanup: Automatic cleanup of temporary resources
Limitations
- Custom Operation Implementation: Requires Rust code changes (no plugin system)
- Complex Parameters: Nested parameter structures have limited support
- Batch Operations: Operations cannot be included in batch/transaction bundles