Nirmitee.io
HealthcareFHIR

FHIR Facade: The Complete Architecture Guide to Modernizing Legacy Healthcare Systems

April 8, 202618 min readUpdated Oct 19, 2026
Written by
Jitendra Choudhary
Jitendra Choudhary

CTO & Co-Founder

CTO & Co-Founder at Nirmitee.io. Architects healthcare integrations across FHIR, SMART on FHIR, ABDM and NHCX, writing from production experience taking hospital software from sandbox to go-live.

FHIR Facade: The Complete Architecture Guide to Modernizing Legacy Healthcare Systems

Many US hospitals and payers still run at least one critical application on legacy software that lacks native FHIR support. CMS-0057-F requires impacted payers (Medicare Advantage organizations, Medicaid and CHIP programs and managed care plans, and QHP issuers on the Federally Facilitated Exchanges) to implement or enhance FHIR APIs, mostly by January 2027. Hospitals are not directly covered by those API requirements, but certified EHRs must offer FHIR APIs under ONC rules. That leaves a real gap between what regulators expect and what legacy systems can do. The FHIR Facade pattern bridges that gap — without ripping out your existing systems.

This guide covers everything: architecture deep-dives, implementation approaches, when to use a facade versus a repository, vendor comparisons, real code examples, and the regulatory deadlines driving adoption. Whether you are a CTO evaluating modernization strategies or an engineer tasked with building FHIR compliance, this is the most comprehensive FHIR Facade resource available.

If the legacy system is on its way out, our healthcare data migration services plan the facade and the move together.

What Is a FHIR Facade?

A FHIR Facade is an architectural layer that exposes a FHIR R4 API for the resources and searches you choose to support, declared in your CapabilityStatement, as a FHIR R4 API on top of an existing non-FHIR system — whether that is a legacy EHR, an HL7 v2 message store, a relational database, or a proprietary clinical data warehouse. Data remains in its original source system. When a FHIR client sends a request, the facade translates it on the fly into whatever query language the legacy system understands, maps the response back to FHIR resources, and returns standards-compliant JSON or XML.

Think of it as a real-time translator sitting between the modern FHIR world and your existing infrastructure. No data migration. No warehouse duplication. No clinical workflow disruption.

FHIR Facade architecture: the facade intercepts FHIR API requests, translates them to legacy system queries, and returns standardized FHIR R4 resources — all without data migration.

The Three Core Functions

Every FHIR Facade performs three operations:

  1. Request interception and routing — The facade receives incoming FHIR REST calls (GET /Patient, POST /Observation, etc.) and routes them to the appropriate legacy system adapter.
  2. Data translation and mapping — This is the heart of the facade. Legacy data formats (HL7 v2 segments, flat database rows, proprietary XML) are mapped to FHIR resource structures. A patient name stored as PID-5 in HL7 v2 becomes a Patient.name HumanName datatype in FHIR R4.
  3. Response assembly — Individual mapped elements are assembled into valid FHIR resources, wrapped in Bundles when needed, and returned with proper HTTP status codes, OperationOutcome resources for errors, and FHIR-compliant pagination.

How a FHIR Facade Works: Request Flow

Understanding the request lifecycle is critical for implementation planning. Here is what happens when a consumer application queries GET /fhir/Patient?family=Smith against a facade:

FHIR Facade request flow: a step-by-step sequence from FHIR client request through facade processing to legacy system query and standardized response.
  1. FHIR request arrives — The client sends a standard FHIR REST request to the facade endpoint.
  2. Authentication and authorization — The facade validates the request using SMART on FHIR scopes (e.g., patient/Patient.read). This is non-negotiable for ONC certification.
  3. Search parameter parsing — FHIR search parameters (family=Smith) are parsed and translated to legacy query equivalents (e.g., SQL WHERE last_name = 'Smith' or HL7 v2 QBP message).
  4. Legacy system query — The facade issues the translated query to the source system.
  5. Response mapping — Legacy results are mapped to FHIR resources using the facade's mapping engine.
  6. FHIR Bundle assembly — Results are wrapped in a FHIR searchset Bundle with proper pagination links, total count, and self link.
  7. Response delivery — The FHIR-compliant response is returned to the client with appropriate HTTP headers.

FHIR Facade Architecture Deep Dive

A production-grade FHIR Facade is not a simple API wrapper. It contains multiple internal components that work together to deliver reliable, performant, and standards-compliant interoperability.

Internal anatomy of a production FHIR Facade: six components from API gateway to audit logging.

Component Breakdown

ComponentPurposeKey Considerations
API Gateway / FHIR Server ShellHandles HTTP routing, content negotiation (JSON/XML), FHIR version detection, and capability statement generationMust support _format, _pretty, _summary parameters per FHIR spec
SMART on FHIR Auth LayerOAuth 2.0 authorization, token validation, scope enforcementRequired for ONC HTI-1 certification. Must support standalone launch, EHR launch, and backend services
Resource RouterMaps incoming FHIR resource type + operation to the correct legacy system adapterPatient queries might go to the MPI, Observations to the lab system, Medications to pharmacy
Mapping EngineTranslates between FHIR resource structures and legacy data modelsThe hardest part. Mapping complexity grows with each resource type and search parameter
Legacy System AdaptersDatabase connectors, HL7 v2 MLLP clients, SOAP clients, REST clients for each source systemEach adapter handles connection pooling, retries, and legacy-specific error handling
Audit LoggerHIPAA-compliant access logging, provenance trackingMust log who accessed what data, when, and under what authorization context

Implementation Example: Python FastAPI Facade

Here is a minimal but functional FHIR Facade built with Python FastAPI that wraps a legacy PostgreSQL patient database:

from fastapi import FastAPI, Query, Request
from fastapi.responses import JSONResponse
from typing import Optional
import asyncpg
import json
from datetime import date

app = FastAPI(title="FHIR Facade", version="R4")

# Search parameters this facade supports. List the same ones in the CapabilityStatement.
SUPPORTED_PARAMS = {"family", "given", "_id"}

# Legacy database connection
async def get_db():
    return await asyncpg.connect(
        host="legacy-db", database="hospital_ehr",
        user="fhir_readonly", password="***"
    )

def map_patient_to_fhir(row: dict) -> dict:
    """Map legacy patient table row to FHIR Patient resource."""
    return {
        "resourceType": "Patient",
        "id": str(row["patient_id"]),
        "meta": {"lastUpdated": row["modified_at"].isoformat()},
        "identifier": [{
            "system": "http://hospital.example.org/mrn",
            "value": row["mrn"]
        }],
        "name": [{
            "use": "official",
            "family": row["last_name"],
            "given": [row["first_name"]]
        }],
        "gender": row["sex"].lower(),  # M/F -> male/female
        "birthDate": row["dob"].isoformat()
    }

def unsupported_search(names: list) -> JSONResponse:
    """400 with an OperationOutcome for search parameters we do not support."""
    return JSONResponse(status_code=400, content={
        "resourceType": "OperationOutcome",
        "issue": [{
            "severity": "error",
            "code": "not-supported",
            "diagnostics": f"Unsupported search parameter(s): {', '.join(sorted(names))}"
        }]
    })

@app.get("/fhir/Patient")
async def search_patient(
    request: Request,
    family: Optional[str] = Query(None),
    given: Optional[str] = Query(None),
    _id: Optional[str] = Query(None, alias="_id")
):
    # Unknown parameters or modifiers (e.g. family:contains): reject by default.
    # With "Prefer: handling=lenient" the client asks us to ignore them instead.
    unknown = [k for k in request.query_params if k not in SUPPORTED_PARAMS]
    lenient = "handling=lenient" in request.headers.get("prefer", "")
    if unknown and not lenient:
        return unsupported_search(unknown)

    db = await get_db()
    # Translate FHIR search params to SQL.
    # FHIR string search defaults to case-insensitive "starts with", so match a prefix.
    conditions, params = [], []
    if family:
        conditions.append(f"last_name ILIKE ${len(params)+1}")
        params.append(f"{family}%")
    if given:
        conditions.append(f"first_name ILIKE ${len(params)+1}")
        params.append(f"{given}%")
    if _id:
        conditions.append(f"patient_id = ${len(params)+1}")
        params.append(int(_id))

    where = " AND ".join(conditions) if conditions else "1=1"
    rows = await db.fetch(f"SELECT * FROM patients WHERE {where} LIMIT 50", *params)
    await db.close()

    entries = [{
        "fullUrl": f"Patient/{row['patient_id']}",
        "resource": map_patient_to_fhir(dict(row))
    } for row in rows]

    return {
        "resourceType": "Bundle",
        "type": "searchset",
        "total": len(entries),
        "entry": entries
    }

@app.get("/fhir/metadata")
async def capability_statement():
    return {
        "resourceType": "CapabilityStatement",
        "status": "active",
        "kind": "instance",
        "fhirVersion": "4.0.1",
        "format": ["json"],
        "rest": [{
            "mode": "server",
            "resource": [{
                "type": "Patient",
                "interaction": [{"code": "read"}, {"code": "search-type"}],
                "searchParam": [
                    {"name": "family", "type": "string"},
                    {"name": "given", "type": "string"},
                    {"name": "_id", "type": "token"}
                ]
            }]
        }]
    }

FHIR string search is case-insensitive and matches the start of the value by default, so family=Smi uses a prefix match: it returns Smith and not Nesmith. Search parameters or modifiers the facade does not support (such as family:contains) get a 400 response with an OperationOutcome, unless the client sends Prefer: handling=lenient. We tested this example with pytest against a mocked database (synthetic rows): GET /Patient?family=Smi returns Smith and not Nesmith, and GET /Patient?family:contains=mit returns 400 with an OperationOutcome.

This 80-line example demonstrates the core facade pattern: receive FHIR requests, translate search parameters to SQL, map database rows to FHIR resources, and return a standards-compliant Bundle. A production implementation would add connection pooling, error handling, pagination, and SMART on FHIR authentication.

FHIR Facade vs. Repository vs. Hybrid: How to Choose

The FHIR Facade is one of three architectural models. Choosing the wrong one wastes months of engineering effort. Here is a definitive comparison.

FHIR Facade vs. Repository vs. Hybrid: three architectural models with different data storage and query patterns.
DimensionFHIR FacadeFHIR RepositoryHybrid (Facade + Cache)
Data storageData stays in source systemData copied to FHIR-native storeHot data cached in FHIR store, rest queried live
Data freshnessAlways real-timeDepends on sync frequency (minutes to hours)Cached data may be stale, live queries are real-time
Query performanceBounded by legacy system speedOptimized for FHIR searchFast for cached resources, legacy-speed for others
FHIR search coverageLimited to what you mapFull FHIR search spec supportFull for cached, limited for live
Write supportComplex — must reverse-map to legacyNative FHIR writesWrites go to repository, synced back to legacy
Implementation effortModerate (per resource type)High upfront, low per-resourceHighest — maintain both paths
Data duplicationNoneFull duplicationPartial duplication
Compliance riskLow — single source of truthHigher — must keep stores in syncMedium — sync logic adds complexity
Best forRead-heavy, real-time access, regulatory complianceAnalytics, research, bulk data exportMixed workloads, gradual migration
Time to first APIWeeksMonthsMonths

The Decision Framework

Decision matrix: choose your FHIR architecture based on four key factors — data freshness, write requirements, query complexity, and migration timeline.

Choose a FHIR Facade when:

  • Your primary need is read access to existing data via FHIR APIs
  • Data freshness is critical — you need real-time results, not stale copies
  • You have regulatory deadlines (CMS-0057-F, ONC HTI-1) and need compliance fast
  • Budget is constrained — you cannot afford a multi-month data migration project
  • The legacy system is staying — there is no plan to replace it

Choose a FHIR Repository when:

  • You need full FHIR search capabilities including chained searches, _include, _revinclude
  • Analytics and bulk data export ($export) are core use cases
  • You are building a new system or doing a greenfield implementation
  • Write operations (creating/updating resources) are a primary workflow

Choose a Hybrid when:

  • You need the real-time accuracy of a facade for clinical data but fast search for analytics
  • You are on a multi-year migration path from legacy to FHIR-native
  • Different resource types have different freshness requirements

Worked decision: facade or materialized store?

Take a payer whose claims live in a legacy adjudication system. It must offer a Patient Access API. Apps will search by _lastUpdated to pick up changes, and the payer also needs bulk $export for its own analytics and data exchange.

  • Live facade: every _lastUpdated search becomes a query against the claims system. If that system does not keep a reliable last-modified time on every row a resource is built from, the facade cannot answer the search correctly. A bulk $export through a live facade means reading and mapping every claim at request time, which can load the production system for hours.
  • Materialized copy: a FHIR store fed from the claims system answers _lastUpdated and $export natively. The cost is freshness and consistency: data is only as current as the last load (seconds with change capture, hours with a nightly batch), and you must reconcile the copy against the source.
  • Typical result: keep a live facade for single-member reads where data must match the claims system exactly, and add a materialized store for _lastUpdated search and bulk export. Write down the agreed freshness (for example, "changes visible within 15 minutes") so everyone tests against the same target.

What the facade does with unsupported searches

A facade rarely supports every search parameter. Decide what happens when a client asks for one you do not support. The FHIR specification lets the client say what it wants with the Prefer header: with handling=strict, return 400 with an OperationOutcome naming the unsupported parameter; with handling=lenient, ignore it and leave it out of the self link of the returned Bundle so the client can see it was not applied. Pick a default, document it, and list the parameters you do support in your CapabilityStatement.

Legacy System Integration: What Can Be Wrapped

A FHIR Facade can wrap virtually any data source. Here are the most common legacy system types and the complexity involved in wrapping each.

A FHIR Facade can wrap six major legacy system types, each with different translation complexity and tool support.
Legacy System TypeTranslation ComplexityCommon ToolsKey Challenge
HL7 v2 Message StoreMediumHAPI v2, Mirth Connect, Rhapsodyv2 segments do not map 1:1 to FHIR resources. OBX alone can become Observation, DiagnosticReport, or DocumentReference depending on context. For an HL7 v2 source specifically, our HL7v2 facade implementation guide shows the gateway, message store and search limits.
Relational Database (SQL)Low-MediumCustom code, ORM mappersSchema-specific. Every hospital's patient table is different. Mapping must be built per deployment.
C-CDA DocumentsMedium-HighHL7 CCDA-on-FHIR IG, XSLTC-CDA sections are document-oriented; FHIR is resource-oriented. Requires section-level parsing and resource extraction.
X12 EDI (837/835/278)HighEdifecs, custom parsersX12 is financial transaction-oriented with complex loop structures. Mapping to clinical FHIR resources requires domain expertise.
Proprietary EHR APIsVariesCustom adaptersVendor-specific data models, auth mechanisms, and rate limits. Epic, Cerner, and MEDITECH each require unique adapters.
Flat Files (CSV/HL7 v2 batch)LowPython/Node.js scriptsBatch-oriented. The facade must handle incremental loads and maintain state for change detection.

Regulatory Drivers: Why Organizations Need FHIR Facades Now

The urgency behind FHIR Facade adoption is not theoretical — it is driven by hard regulatory deadlines with financial penalties for non-compliance.

The Regulatory Timeline

According to the 2025 State of FHIR Survey by HL7 and Firely (82 participants across 52 countries), FHIR is mandated or recommended in 73% of countries with health data regulation. In the US specifically:

  • ONC HTI-1 Final Rule (January 2025) — Certified health IT must support USCDI v3 through its FHIR R4 APIs, with USCDI v3 as the baseline from January 1, 2026. This means certified EHRs must expose patient data through FHIR. Organizations using legacy systems without native FHIR need a facade to comply.
  • CMS-0057-F prior authorization timeframes (January 2026): from January 1, 2026, impacted payers other than QHP issuers on the Exchanges must decide prior authorization requests within 72 hours (expedited) or 7 calendar days (standard), and impacted payers must publicly report prior authorization metrics. The Prior Authorization API itself is due from January 2027. Payers running legacy claims adjudication systems often need facades to expose this data.
  • CMS-0057-F Full API Mandate (January 2027) — Impacted payers must have the Provider Access API, Payer-to-Payer API and Prior Authorization API in place, generally from January 1, 2027 (exact dates vary by payer type). The Patient Access API already existed under CMS-9115-F; CMS-0057-F adds to it, including prior authorization information. For many payers this is the largest FHIR deadline they have faced.

For payer organizations, the math is simple: a FHIR Facade that wraps your existing claims platform can be built in weeks to months. A full FHIR repository migration takes 12-24 months. With January 2027 approaching, the facade is often the only viable path to compliance.

FHIR Adoption Statistics

The data confirms that FHIR is no longer optional:

  • US certified EHRs: the Cures Act and ONC rules require certified EHRs to provide standardized FHIR APIs
  • Over 70% of countries in the survey of 82 participants report active FHIR use for at least a few national use cases (HL7/Firely 2025 Survey)
  • Lack of FHIR expertise is a common implementation barrier, alongside funding, version fragmentation and tooling gaps that the same survey names
  • Many healthcare providers still rely on legacy software
  • A large share of healthcare IT budgets goes to maintaining legacy systems

These numbers explain why FHIR Facades are seeing explosive adoption: organizations need FHIR compliance but cannot replace their core systems fast enough.

Implementation Approaches: Build vs. Buy

There are four main paths to implementing a FHIR Facade, each with different trade-offs.

ApproachTechnologyBest ForEffortCost Model
Open-Source FrameworkHAPI FHIR Plain Server (Java), Aidbox (Docker), python-fhirEngineering-heavy orgs with FHIR expertiseMedium-HighFree license, engineering cost
Commercial FHIR PlatformFirely Server (.NET), Smile CDR (Java), InterSystems IRISOrgs needing vendor support + SLALow-MediumLicense + implementation
Cloud-Native ServiceAzure Health Data Services, AWS HealthLake, Google Cloud Healthcare APICloud-first orgs, already on the platformLowPay-per-use, scaling costs
Custom BuildPython (FastAPI/Django), Node.js (Express), GoSpecific legacy systems, unique requirementsHighFull engineering ownership

How to Choose

Start with HAPI FHIR Plain Server if you have Java developers and want maximum control. HAPI is the reference implementation — battle-tested in thousands of deployments. The Plain Server mode is specifically designed for facades: you implement resource provider interfaces and HAPI handles everything else (parsing, serialization, search parameter handling, capability statement).

Use a commercial platform (Firely, Smile CDR) if you need certification support, vendor SLAs, and faster time-to-market. Commercial platforms include pre-built mapping tools, SMART on FHIR servers, and compliance testing suites.

Go cloud-native if you are already on Azure/AWS/GCP and your data is accessible from the cloud (our guide to choosing a FHIR server compares open source, commercial and cloud routes). Azure Health Data Services includes a built-in FHIR server with conversion pipelines for HL7 v2 and C-CDA.

Build custom only when your legacy system is so unique that no framework supports it, or when you need a lightweight facade for a narrow use case (e.g., wrapping a single legacy API for a specific AI agent integration).

Incremental Migration: The Phased Approach

One of the most powerful aspects of the FHIR Facade pattern is that it enables incremental modernization. You do not need to wrap every resource type on day one.

Recommended Phasing

  1. Phase 1 (Weeks 1-4): Patient Demographics — Start with the Patient resource. This is the foundation of every FHIR interaction, has relatively simple mapping, and immediately enables patient-facing apps.
  2. Phase 2 (Weeks 5-8): Clinical Core — Add Condition, AllergyIntolerance, and Medication resources. These cover the US Core Data for Interoperability (USCDI) required elements.
  3. Phase 3 (Weeks 9-12): Diagnostics — Add Observation (lab results, vitals), DiagnosticReport, and clinical data for dashboards. These resources have higher mapping complexity due to varied coding systems.
  4. Phase 4 (Weeks 13-16): Documents and Operations — Add DocumentReference (for C-CDA/PDF access), Encounter, and Procedure. Implement bulk data export ($export) if required.
  5. Phase 5 (Ongoing): Advanced Features — Add write operations, subscriptions, and remaining USCDI resources as needed. At this point, evaluate whether to begin migrating high-query resources to a hybrid model.

Common Pitfalls and Anti-Patterns

After working with healthcare organizations across the US and India on FHIR implementations, these are the mistakes we see most often:

1. Mapping Everything at Once

Trying to map all 150+ FHIR resource types before launching. Start with the 8-10 resources that cover your use case (US Core profiles cover most regulatory requirements with ~20 resources).

2. Ignoring Search Parameter Complexity

Each FHIR search parameter you support requires a translation rule. Supporting Patient?name=Smith is simple. Supporting Observation?code=http://loinc.org|85354-9&date=gt2024-01-01&_include=Observation:patient is an order of magnitude more complex. Plan your search parameter support deliberately.

3. Skipping the Capability Statement

The /metadata endpoint is not optional. It is how FHIR clients discover what your server supports. An inaccurate capability statement causes cascading failures in client applications and will fail ONC certification testing.

4. No Caching Strategy

Pure facades query the legacy system on every request. For high-traffic resources like Patient, this can overwhelm the legacy database. Implement HTTP caching headers (ETag, Last-Modified) and consider a thin cache layer for frequently accessed resources.

5. Underestimating Terminology Mapping

Legacy systems often use local codes ("Lab code 4532") instead of standard terminologies (LOINC, SNOMED CT, ICD-10). Your facade needs a terminology mapping layer or crosswalk tables to produce standards-compliant resources. Without this, your FHIR API returns syntactically valid but semantically useless data.

6. Treating Authorization as an Afterthought

SMART on FHIR authorization is required for ONC certification and is expected by every modern FHIR client. Bolting it on after building the facade creates security gaps. Design your auth layer from day one.

Performance Considerations

A FHIR Facade's performance is bounded by the slowest legacy system it wraps. Key optimization strategies:

  • Connection pooling — Maintain persistent connections to legacy databases instead of opening/closing per request
  • Parallel queries — When a FHIR Bundle requires data from multiple legacy systems, query them concurrently
  • Pagination enforcement — Never return unbounded result sets. Enforce _count limits (default: 20-50 resources per page)
  • Response caching — Cache frequently accessed, slowly changing resources (e.g., Patient demographics) with short TTLs (5-15 minutes)
  • Lazy loading — Only resolve _include and _revinclude references when explicitly requested

Target response times: under 500ms for single resource reads, under 2 seconds for search queries returning up to 50 results. If your legacy system cannot meet these targets, consider the hybrid approach with a FHIR cache for hot data.

FHIR R4 to R6: Future-Proofing Your Facade

FHIR R4 is the current standard, but FHIR R6 is expected in late 2026 with most resources reaching normative status. How does this affect your facade strategy?

The good news: FHIR maintains strong backward compatibility. A well-designed facade with a clean mapping layer can support multiple FHIR versions simultaneously by implementing version-specific mappers behind the same legacy system adapter. The facade pattern actually makes version migration easier than a repository migration, because you are only changing the output mapping — not migrating stored data.

Design recommendation: Keep your mapping logic in a separate module from your legacy system adapter. When R6 arrives, you add new mappers without touching your database integration code.

Conclusion

The FHIR Facade is not a temporary workaround — it is a proven architectural pattern used by organizations from 50-bed hospitals to national payer networks. It delivers FHIR compliance without the risk, cost, and disruption of a full system replacement.

With CMS-0057-F deadlines approaching, FHIR skills scarce and many organizations still running legacy systems, the facade pattern will likely grow in importance. Start with Patient, prove the pattern works, and expand from there.

If you are planning this work, our team can help with the FHIR facade and API build and wider legacy system modernization.

Ready to scale?

Talk to our healthcare engineering team about building, integrating, and shipping faster.

Frequently Asked Questions

What is a FHIR Facade in healthcare architecture?

A FHIR Facade is an architectural layer that exposes a FHIR R4 API, for the resources and searches you choose to support and declare in your CapabilityStatement, on top of an existing non-FHIR system, such as a legacy EHR, an HL7 v2 message store, a relational database, or a proprietary clinical data warehouse. Data stays in its original source system: the facade translates each FHIR request on the fly into the legacy system's query language, maps the response back into FHIR resources, and returns standards-compliant JSON or XML with no data migration.

Why are hospitals adopting the FHIR Facade pattern now?

Regulatory deadlines are the main driver. CMS-0057-F requires impacted payers to implement or enhance FHIR APIs, mostly by January 2027, and ONC rules require certified EHRs to offer FHIR APIs. Hospitals are not directly covered by the CMS-0057-F API requirements, but many hospitals and payers still run at least one critical application on legacy software without native FHIR support. The facade pattern bridges that gap without ripping out existing systems, avoiding data migration, warehouse duplication, and clinical workflow disruption.

How does a FHIR Facade process an API request?

The request flows through seven steps: the FHIR REST request arrives, the facade validates it using SMART on FHIR scopes like patient/Patient.read, search parameters such as family=Smith are parsed and translated into legacy equivalents like a SQL WHERE clause or an HL7 v2 QBP message, the legacy system is queried, results are mapped to FHIR resources, the resources are wrapped in a searchset Bundle with pagination links and totals, and the FHIR-compliant response returns to the client.

What components make up a production-grade FHIR Facade?

A production FHIR Facade contains six components: an API gateway or FHIR server shell handling routing and content negotiation, a SMART on FHIR OAuth 2.0 auth layer required for ONC HTI-1 certification, a resource router directing each resource type to the right legacy adapter, a mapping engine translating between FHIR and legacy data models, legacy system adapters with connection pooling and retries, and a HIPAA-compliant audit logger tracking who accessed what data and under what authorization.

What is the hardest part of building a FHIR Facade?

The mapping engine is the hardest part of a FHIR Facade, because translating between FHIR resource structures and legacy data models grows in complexity with every resource type and search parameter supported. A patient name stored as PID-5 in HL7 v2, for example, must become a Patient.name HumanName datatype in FHIR R4. Healthcare engineering teams like Nirmitee's typically start with the highest-value resources and expand mappings incrementally while keeping the source system untouched.

How does Nirmitee.io approach healthcare software development?

Nirmitee.io follows a healthcare-first engineering approach — every solution is built with HIPAA compliance, HL7/FHIR interoperability standards, and clinical workflow requirements at the core. We combine domain expertise with modern engineering practices to deliver production-ready systems.
Share