> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ferrum.thalamiq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Operations

> FHIR operations (e.g. $validate) at system, type, or instance level.

## 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

Ferrum 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:

```bash theme={null}
# 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"
```

<Note>
  The `$` character in URLs must be escaped as `\$` in bash/curl commands.
</Note>

## Built-in Operations

Ferrum 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:

```bash theme={null}
curl "http://localhost:8080/fhir/ValueSet/\$expand?url=http://hl7.org/fhir/ValueSet/administrative-gender&count=10"
```

POST example:

```bash theme={null}
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, Ferrum 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

Ferrum 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:

```bash theme={null}
# 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:

```json theme={null}
{
  "resourceType": "Parameters",
  "parameter": [
    { "name": "job-id", "valueString": "pkg-install-12345" },
    { "name": "status", "valueString": "accepted" }
  ]
}
```

### ValueSet Expansion

Expand a ValueSet to get all its codes:

```bash theme={null}
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:

```bash theme={null}
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:

```json theme={null}
{
  "resourceType": "Parameters",
  "parameter": [
    { "name": "result", "valueBoolean": true },
    { "name": "display", "valueString": "Male" }
  ]
}
```

### Search Index Rebuild

Rebuild search parameter indexes:

```bash theme={null}
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, Ferrum automatically:

1. Registers the operation in the operation registry
2. Validates the operation context (system/type/instance)
3. Enables parameter validation
4. Makes the operation available at appropriate endpoints

Example OperationDefinition:

```json theme={null}
{
  "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:

```rust theme={null}
#[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:

1. **Request**: Client submits operation request
2. **Acceptance**: Server returns 202 Accepted with job ID
3. **Polling**: Client polls job status using admin endpoints
4. **Completion**: Job completes with success/failure status

Example async operation flow:

```bash theme={null}
# 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:

```yaml theme={null}
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:

```bash theme={null}
# 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
```

## Performance Considerations

* **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

## Related Documentation

* [Learn FHIR: Operations](/learn-fhir/operations)
* [API Reference: System Operations](/api-reference/operations/system)
* [API Reference: Type Operations](/api-reference/operations/type)
* [API Reference: Instance Operations](/api-reference/operations/instance)
* [Server guide: Packages](/server/packages)
* [FHIR Operations Specification](https://hl7.org/fhir/operations.html)
