Usage Examples
FHIRPath Engine Usage Examples
Section titled “FHIRPath Engine Usage Examples”This document provides comprehensive examples of how to use the FHIRPath Rust engine in various scenarios.
Table of Contents
Section titled “Table of Contents”- Basic Usage
- CLI Tool Examples
- Rust API Examples
- Node.js Integration Examples
- Advanced Usage Patterns
Basic Usage
Section titled “Basic Usage”Simple Property Access
Section titled “Simple Property Access”use fhirpath_core::evaluator::evaluate_expression;use serde_json::json;
let patient = json!({ "resourceType": "Patient", "id": "example", "name": [{ "family": "Smith", "given": ["John"] }], "gender": "male"});
// Access basic propertieslet result = evaluate_expression("resourceType", patient.clone()).unwrap();println!("Resource Type: {:?}", result);
let result = evaluate_expression("gender", patient.clone()).unwrap();println!("Gender: {:?}", result);
Array and Path Navigation
Section titled “Array and Path Navigation”// Access nested propertieslet result = evaluate_expression("name.family", patient.clone()).unwrap();println!("Family Name: {:?}", result);
let result = evaluate_expression("name.given", patient.clone()).unwrap();println!("Given Names: {:?}", result);
// Array indexinglet result = evaluate_expression("name[0].family", patient.clone()).unwrap();println!("First Name Family: {:?}", result);
CLI Tool Examples
Section titled “CLI Tool Examples”The FHIRPath CLI tool provides an easy way to test expressions against FHIR resources.
Basic Evaluation
Section titled “Basic Evaluation”# Evaluate a simple expressionoctofhir-fhirpath eval "resourceType" --resource patient.json
# Evaluate with pretty formattingoctofhir-fhirpath eval "name.family" --resource patient.json --format pretty
# Evaluate complex expressionsoctofhir-fhirpath eval "name.where(use = 'official').family" --resource patient.json
Expression Validation
Section titled “Expression Validation”# Validate FHIRPath expression syntaxoctofhir-fhirpath validate "Patient.name.family"octofhir-fhirpath validate "invalid..expression"
Working with Different Resource Types
Section titled “Working with Different Resource Types”# Observation resourceoctofhir-fhirpath eval "code.coding.system" --resource observation.json
# Bundle resourceoctofhir-fhirpath eval "entry.resource.resourceType" --resource bundle.json
# Medication resourceoctofhir-fhirpath eval "ingredient.item.display" --resource medication.json
Rust API Examples
Section titled “Rust API Examples”Basic Integration
Section titled “Basic Integration”use fhirpath_core::evaluator::evaluate_expression;use fhirpath_core::model::FhirPathValue;use serde_json;
fn main() -> Result<(), Box<dyn std::error::Error>> { // Load FHIR resource from file let resource_json = std::fs::read_to_string("patient.json")?; let resource: serde_json::Value = serde_json::from_str(&resource_json)?;
// Evaluate FHIRPath expression let result = evaluate_expression("Patient.name.family", resource)?;
// Process result match result { FhirPathValue::Collection(values) => { for value in values { match value { FhirPathValue::String(s) => println!("Family name: {}", s), _ => println!("Non-string value: {:?}", value), } } } _ => println!("Unexpected result type: {:?}", result), }
Ok(())}
Error Handling
Section titled “Error Handling”use fhirpath_core::evaluator::evaluate_expression;use fhirpath_core::errors::FhirPathError;
fn safe_evaluation(expression: &str, resource: serde_json::Value) { match evaluate_expression(expression, resource) { Ok(result) => println!("Result: {:?}", result), Err(FhirPathError::ParseError(msg)) => { eprintln!("Parse error: {}", msg); } Err(FhirPathError::EvaluationError(msg)) => { eprintln!("Evaluation error: {}", msg); } Err(FhirPathError::TypeError(msg)) => { eprintln!("Type error: {}", msg); } Err(err) => eprintln!("Other error: {:?}", err), }}
Performance Optimization
Section titled “Performance Optimization”use fhirpath_core::evaluator::evaluate_expression_optimized;
// Use optimized evaluation for better performancelet result = evaluate_expression_optimized("complex.expression.here", resource)?;
Streaming Mode for Large Resources
Section titled “Streaming Mode for Large Resources”use fhirpath_core::evaluator::evaluate_expression_streaming;use std::fs::File;
let file = File::open("large-bundle.json")?;let result = evaluate_expression_streaming("entry.resource.resourceType", file)?;
Node.js Integration Examples
Section titled “Node.js Integration Examples”Basic Usage
Section titled “Basic Usage”const { FhirPathEngine } = require('@octofhir/fhirpath');
const engine = new FhirPathEngine();
const patient = { resourceType: "Patient", id: "example", name: [{ family: "Smith", given: ["John"] }], gender: "male"};
// Synchronous evaluationtry { const result = engine.evaluate("name.family", JSON.stringify(patient)); console.log("Family name:", JSON.parse(result));} catch (error) { console.error("Evaluation error:", error.message);}
Asynchronous Evaluation
Section titled “Asynchronous Evaluation”// Asynchronous evaluation for CPU-intensive operationsasync function evaluateAsync() { try { const result = await engine.evaluateAsync("complex.expression", JSON.stringify(largeResource)); console.log("Result:", JSON.parse(result)); } catch (error) { console.error("Async evaluation error:", error.message); }}
evaluateAsync();
Expression Validation
Section titled “Expression Validation”// Validate expression syntaxconst isValid = engine.validate("Patient.name.family");console.log("Expression is valid:", isValid);
const isInvalid = engine.validate("invalid..expression");console.log("Invalid expression:", isInvalid);
Utility Functions
Section titled “Utility Functions”const { exists } = require('@octofhir/fhirpath');
// Check if expression returns any resultsconst hasResults = exists("name.where(use = 'official')", JSON.stringify(patient));console.log("Has official name:", hasResults);
Advanced Usage Patterns
Section titled “Advanced Usage Patterns”Conditional Logic
Section titled “Conditional Logic”// Using where() function for filteringlet result = evaluate_expression("name.where(use = 'official').family", resource)?;
// Boolean expressionslet result = evaluate_expression("gender = 'male'", resource)?;
// Existence checkslet result = evaluate_expression("name.exists()", resource)?;
Mathematical Operations
Section titled “Mathematical Operations”// Numeric calculationslet result = evaluate_expression("age + 10", resource)?;
// Comparisonslet result = evaluate_expression("age > 18", resource)?;
String Operations
Section titled “String Operations”// String concatenationlet result = evaluate_expression("name.family + ', ' + name.given.first()", resource)?;
// String functionslet result = evaluate_expression("name.family.upper()", resource)?;
Working with Collections
Section titled “Working with Collections”// Collection operationslet result = evaluate_expression("name.count()", resource)?;
// First and last elementslet result = evaluate_expression("name.first().family", resource)?;let result = evaluate_expression("telecom.last().value", resource)?;
Complex Nested Expressions
Section titled “Complex Nested Expressions”// Multi-level navigationlet result = evaluate_expression( "contact.where(relationship.coding.code = 'N').name.family", resource)?;
// Combining multiple conditionslet result = evaluate_expression( "telecom.where(system = 'email' and use = 'work').value", resource)?;
Best Practices
Section titled “Best Practices”1. Error Handling
Section titled “1. Error Handling”Always handle potential errors when evaluating expressions:
match evaluate_expression(expression, resource) { Ok(result) => { // Process successful result } Err(error) => { // Handle error appropriately log::error!("FHIRPath evaluation failed: {}", error); }}
2. Performance Considerations
Section titled “2. Performance Considerations”- Use
evaluate_expression_optimized
for complex expressions - Use streaming mode for large resources
- Cache compiled expressions when evaluating the same expression multiple times
3. Type Safety
Section titled “3. Type Safety”Always check the result type before processing:
match result { FhirPathValue::Collection(values) => { for value in values { match value { FhirPathValue::String(s) => println!("String: {}", s), FhirPathValue::Boolean(b) => println!("Boolean: {}", b), FhirPathValue::Integer(i) => println!("Integer: {}", i), _ => println!("Other type: {:?}", value), } } } _ => println!("Not a collection: {:?}", result),}
4. Resource Validation
Section titled “4. Resource Validation”Validate FHIR resources before evaluation:
// Ensure resource has required structureif !resource.is_object() { return Err("Resource must be a JSON object".into());}
if resource.get("resourceType").is_none() { return Err("Resource must have a resourceType".into());}
Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”- Parse Errors: Check expression syntax
- Type Errors: Ensure operations are performed on compatible types
- Empty Results: Verify the path exists in the resource
- Performance Issues: Consider using optimized evaluation or streaming mode
Debug Mode
Section titled “Debug Mode”Enable debug logging to troubleshoot issues:
env_logger::init();log::debug!("Evaluating expression: {}", expression);
For more detailed examples and API documentation, see the generated rustdoc documentation.