Runbeam logo

API transforms for open source healthcare: solving interoperability without the rewrite

Open source healthcare teams don't have time for rewrites. Here's how to use Harmony as an integration boundary to translate protocols, transform payloads, and enforce policy—so you can ship interop features without touching your core application.

Christopher Skene
Christopher Skene
Head of Magic
January 28, 2026
  • Healthcare
  • Interoperability
  • Open Source
  • FHIR
  • DICOM

If you're building open source healthcare software, you've probably hit this wall: your system works fine internally, but the moment you need to exchange data with a lab, a PACS, a national eRequesting service, or even just another hospital's API, things get complicated fast.

The problem isn't that standards don't exist. It's that "interoperability" isn't one standard—it's a long tail of partially-overlapping standards, profiles, versions, and local conventions that all claim to be "FHIR" or "DICOM" but somehow don't quite speak to each other.

Harmony, the Runbeam gateway, is built to sit at that boundary. It's a proxy runtime and API gateway that translates protocols, transforms payloads, and enforces policy—so you can keep your application simple and stable while the messy parts of interoperability happen somewhere else.

This post walks through the common interoperability problems open source healthcare teams face, and shows you how to solve them with concrete examples from real Harmony workloads.

The three problems that keep coming up

Problem 1: "We need FHIR, but nobody speaks the same FHIR"

Everyone says they support FHIR. But in practice:

  • One partner wants FHIR R4, another wants R5
  • Search parameters don't match what your backend actually supports
  • Implementation guides add mandatory fields your data model doesn't have
  • Your UI can only send simple HTTP requests, not full FHIR transaction bundles

You end up writing bespoke mapping code that's tightly coupled to both your application and the partner's expectations. When the IG updates or you add a new partner, you're back in the codebase again.

How Harmony helps: Put a stable external contract in front of your system. Harmony normalizes incoming requests (path rewriting, query param extraction, header manipulation), applies JOLT transforms to reshape payloads, routes to your backend, and transforms responses back to whatever shape your consumers expect.

The transforms are configuration, not code. When the IG evolves, you update the transform spec—not your application.

Problem 2: Imaging interoperability (FHIR on the outside, DICOM on the inside)

Imaging is where a lot of projects stall:

  • Your app wants to query for studies using FHIR ImagingStudy resources
  • Your PACS speaks DICOM DIMSE (or maybe DICOMweb if you're lucky)
  • You need secure retrieval URLs (WADO-RS, JMIX, whatever) plus auth and audit trails

Building a FHIR-to-DICOM bridge from scratch is a multi-month project. Most teams either give up on standards, or they hard-code something brittle that breaks when vendors update their systems.

How Harmony helps: Act as the translation layer. Accept a FHIR search request, convert the search parameters into DICOM C-FIND query tags, send the query to the PACS, convert the DICOM response back into a FHIR Bundle, and enrich it with download URLs. All the protocol handling is config + transforms.

Problem 3: Security and policy at the integration boundary

Open source implementations often need to be more secure than the systems behind them—especially when you're exposing internal services to external partners or national infrastructure.

You need:

  • Consistent authentication and authorization across all endpoints
  • Rate limiting and IP allowlisting
  • Path and method filtering (deny everything except the specific operations you support)
  • Audit logging for compliance and troubleshooting

Scattering these controls across multiple services is a recipe for security gaps.

How Harmony helps: Middleware pipelines make policy explicit and repeatable. You define the auth, rate limit, path filter, and logging rules once in the pipeline config. Every request flows through the same middleware chain, in order, before it ever reaches your backend.

Example 1: FHIR to Legacy—bridging modern and older systems

Many healthcare organisations have legacy patient management systems, lab systems, or custom APIs that don't speak FHIR. Meanwhile, new applications and EHR integrations increasingly require FHIR R4 compliance. Rewriting those legacy systems isn't practical—but you still need them to participate in modern healthcare data exchange.

The FHIR to Legacy HTTP and Legacy HTTP to FHIR workloads demonstrate a bidirectional bridge pattern that solves this without touching your existing systems:

Flow 1: FHIR → Legacy (the "legacy adapter")

Your FHIR-enabled EHR sends a standard Patient resource:

curl -X POST http://127.0.0.1:8080/Patient \
  -H "Content-Type: application/fhir+json" \
  -d '{
    "resourceType": "Patient",
    "id": "12345",
    "name": [{ "family": "Smith", "given": ["John", "William"] }],
    "birthDate": "1990-01-15",
    "gender": "male",
    "identifier": [{ "system": "http://hospital.org/mrn", "value": "MRN-001234" }],
    "address": [{
      "line": ["123 Main Street", "Apt 4B"],
      "city": "Boston",
      "state": "MA",
      "postalCode": "02101"
    }]
  }'

Harmony transforms this FHIR Patient into flat JSON that your legacy system expects:

{
  "patient_id": "12345",
  "first_name": "John",
  "middle_name": "William",
  "last_name": "Smith",
  "date_of_birth": "1990-01-15",
  "sex": "male",
  "address_line1": "123 Main Street",
  "address_line2": "Apt 4B",
  "city": "Boston",
  "state": "MA",
  "zip_code": "02101",
  "api_version": "1.0",
  "record_type": "patient"
}

Flow 2: Legacy → FHIR (the "FHIR facade")

When your legacy system needs to create or update records in a FHIR server, it sends its native format:

curl -X POST http://127.0.0.1:8080/api/patients \
  -H "Content-Type: application/json" \
  -d '{
    "patient_id": "12345",
    "first_name": "John",
    "last_name": "Smith",
    "dob": "1990-01-15",
    "gender": "M",
    "mrn": "MRN-001234",
    "phone": "+1-555-123-4567"
  }'

Harmony transforms this into a fully compliant FHIR Patient resource—adding proper resourceType, meta profiles, identifier codings, and gender value mapping (Mmale)—before forwarding to your FHIR server.

What you gain

  • Keep legacy systems running: Your existing patient management systems don't need to change
  • Adopt FHIR incrementally: New applications can use FHIR while old ones continue working
  • Centralize field mapping: JOLT transforms handle the conversion logic in one place, not scattered across applications

Example 2: FHIR ImagingStudy queries that talk to a DICOM PACS

The FHIR-DICOM workload demonstrates the full translation loop for imaging:

The flow

  1. Accept a FHIR query:

    curl "http://localhost:8081/fhir/ImagingStudy?patient=PID156695" \
      -H "Accept: application/fhir+json"
  2. Extract search parameters and convert to DICOM tags:

    • patient=PID156695 → DICOM tag 00100020 (PatientID)
    • modality=CT → DICOM tag 00080060 (Modality)
  3. Send a DICOM C-FIND query to the PACS

  4. Convert DICOM responses back to FHIR:

    {
      "resourceType": "Bundle",
      "type": "searchset",
      "entry": [
        {
          "resource": {
            "resourceType": "ImagingStudy",
            "id": "1.2.826.0.1.3680043.9.7133.3280065491876470",
            "status": "available",
            "subject": { "reference": "Patient/PID156695" },
            "endpoint": [
              {
                "address": "/api/jmix?studyInstanceUid=1.2.826..."
              }
            ]
          }
        }
      ]
    }
  5. Enrich with retrieval URLs: The endpoint field contains JMIX download URLs so clients can retrieve images without knowing anything about DICOM.

The technical details

The workload uses context-aware JOLT transforms:

  • Query parameter extraction: metadata_transform pulls patient, modality, etc. from the FHIR request and maps them to target_details.metadata
  • DICOM identifier construction: A JOLT transform reads context.target_details.metadata and builds a DICOM C-FIND identifier with the correct tags
  • Response enrichment: Another transform adds JMIX URLs to each study based on the StudyInstanceUID

The transforms are declarative JSON specs. No custom DICOM parsing code in your application.

What you gain

  • Your app stays FHIR-native: You don't need DICOM libraries or protocol knowledge in your frontend
  • Security in one place: Auth, logging, and rate limits apply at the Harmony boundary—before the PACS ever sees the request
  • Vendor independence: Swap out the PACS backend without touching your application (just update the backend target in config)

How to try this in your own project

If you're working on an open source EHR, registry, referral system, or patient portal, here's the fastest path:

1. Pick a starting workload

Browse the workloads catalogue and find one close to your problem:

  • FHIR to Legacy / Legacy to FHIR: Bridge FHIR-enabled applications with legacy systems that don't speak FHIR
  • FHIR-DICOM: Bridge clinical apps and imaging systems
  • DICOM-to-DICOMweb: Translate legacy DIMSE to modern DICOMweb
  • SOAP-to-JSON: Wrap old SOAP services with REST APIs

2. Deploy and wire up your backends

Each workload includes:

  • Pipeline config (TOML files defining endpoints, middleware, backends)
  • Transform specs (JOLT transforms for request/response reshaping)
  • Example requests and expected responses

Replace the example backend targets with your real systems (your FHIR server, PACS, lab API, etc.).

3. Iterate on transforms

The transform specs control how data flows between your external contract and your internal systems. Start with the examples, then adjust:

  • Add fields that your implementation guide requires
  • Strip fields that your backend doesn't support
  • Apply terminology mappings or code system conversions

Transforms are JSON. They're testable in isolation. No redeployment needed.

4. Add policy middleware

Before you open the endpoint to partners, add:

  • Authentication: JWT validation, API keys, client certificates
  • Path filtering: Deny everything except the specific FHIR operations you support
  • Rate limiting: Protect your backend from overload
  • Logging/audit: Capture requests for compliance and debugging

All of this is middleware config—no application changes.

5. Expand incrementally

Once the first integration works, you can:

  • Add new partners by creating new transform variants
  • Support multiple FHIR versions by branching on Accept headers
  • Route to different backends based on request characteristics

The pattern scales because the integration logic lives outside your core application.

What this means for open source healthcare teams

Most open source healthcare projects don't have the budget or timeline to rewrite their systems every time a new integration requirement shows up. Harmony gives you a way to solve interoperability problems without touching your core application:

  • Protocol translation happens in config and transforms
  • Policy enforcement happens in middleware pipelines
  • Schema evolution happens by updating transform specs, not deploying new code

You can ship FHIR, DICOM, HL7v2, or whatever your partners need—while keeping your application architecture simple and stable.


If you want specific guidance for your use case, let us know what you're integrating (EHR/referral system/lab/PACS), which standards you need to support (FHIR R4/R5, DICOM/DICOMweb, HL7v2), and what your "external contract" needs to look like. We'll point you to the right starting workload and help you get it working.

Read next