Middleware
Middleware extends the request/response pipeline to authenticate, enrich, or transform data as it flows through Harmony.
Overview
Middleware operates within Harmony's pipeline executor and processes envelopes for all protocols (HTTP, FHIR, DICOM/DICOMweb, JMIX, HL7).
Pipeline Flow
Middleware types:
- Authentication - Run early in the pipeline (incoming side)
- Transformation - Can run on incoming requests, outgoing responses, or both
- Path filtering - Rejects requests based on URL patterns
- Metadata transformation - Modifies request metadata for routing decisions
Key principle: Middleware is protocol-agnostic. It works with envelopes, not raw protocol data.
Error Handling
Middleware errors are mapped to HTTP status codes:
- Authentication failures (JWT/Basic auth issues):
401 Unauthorized - All other middleware failures (transform errors, internal failures):
500 Internal Server Error
This ensures only actual authentication problems return 401, while configuration errors and other issues correctly return 500.
Middleware Catalog
Authentication
- Basic Auth → - Validate
Authorization: Basiccredentials. - JWT Auth → - Verify
Authorization: Bearertokens (RS256/HS256).
Transformation
- Transform (JOLT) → - Apply JSON-to-JSON transformations.
- Metadata Transform → - Apply JOLT transforms to request metadata.
Filtering
- Path Filter → - Reject requests that don’t match allowed URL patterns.
Healthcare-specific
- JMIX Builder → - Build JMIX packages from DICOM operation responses.
- DICOMweb Bridge → - Bridge DICOMweb (QIDO/WADO) to DIMSE operations.
- DICOM Flatten → - Flatten/unflatten DICOM JSON for simplified processing.
Debugging
- Log Dump → - Dump envelopes to logs with configurable redaction.
Middleware Ordering
Order matters! Middleware executes in the order defined in your pipeline.
Recommended ordering:
# 1. Authentication first - reject unauthorized requests early
[[middleware]]
type = "jwt_auth"
# 2. Path filtering - reject invalid paths before processing
[[middleware]]
type = "path_filter"
# 3. Request transformations
[[middleware]]
type = "metadata_transform"
# 4. Backend processing happens here
# 5. Response transformations
[[middleware]]
type = "transform"
apply = "right"
# 6. Protocol bridges (DICOMweb, JMIX)
[[middleware]]
type = "dicomweb_bridge"
Best Practices
Performance
- Place authentication middleware first to reject requests early
- Use
fail_on_error = falsefor optional transformations - Enable
skip_hashingandskip_listingfor JMIX when appropriate - Cache JOLT specifications by reusing middleware instances
Security
- Always use RS256 for JWT in production
- Never commit secrets or keys to version control
- Use environment variables for sensitive config values
- Restrict path filter rules to minimum necessary paths
Debugging
- Enable
RUST_LOG=harmony::middleware=debugfor detailed logs - Test transformations independently before deploying
- Use
fail_on_error = falseduring development to see partial results - Check middleware order if requests aren't processed as expected
Examples
FHIR with Authentication
[[middleware]]
type = "jwt_auth"
public_key_path = "/etc/harmony/jwt_public.pem"
issuer = "https://auth.example.com"
audience = "fhir-api"
[[middleware]]
type = "path_filter"
[middleware.options]
rules = ["/Patient", "/Observation", "/ImagingStudy"]
DICOM to DICOMweb Bridge
[[middleware]]
type = "dicomweb_bridge"
[[middleware]]
type = "jmix_builder"
[middleware.options]
skip_hashing = true
Transform Pipeline
# Transform request
[[middleware]]
type = "transform"
[middleware.options]
spec_path = "transforms/request.json"
apply = "left"
# Transform response
[[middleware]]
type = "transform"
[middleware.options]
spec_path = "transforms/response.json"
apply = "right"