Lesson 47 of 51 · The Integration Engine
Transformation, Routing, and Filtering
Channels: how an engine is configured
The previous lesson described what an engine does to each message — filter, transform, route, send. Those functions are not abstract; they are configured as channels (some products call them interfaces or routes). A channel is a named pipeline that connects one source to one or more destinations, with processing steps in between. The source defines how messages arrive — a listening port, a watched folder, a database query, an inbound API call. Each destination defines where a processed message goes and over what protocol. Everything in this lesson — filtering, transformation, routing — is configuration that lives inside a channel.
Thinking in channels matters because it locates the work. When two systems do not agree on a format or a code set, you do not change either system; you add or adjust a channel. The engine becomes the single place where the organization encodes its knowledge of how its systems differ 1.
Filtering: deciding what proceeds
A filter is a rule that decides whether a given message should continue down a route at all. A message that fails the filter is simply dropped from that route — not an error, just “this destination does not need this one.” Filters typically key off easily inspected fields: the message type (forward admissions but not appointment notifications), the sending or receiving facility, an order type, or a patient location. A lab system, for instance, has no use for a registration update that carries no orderable, so a filter on message type keeps it out.
Filtering is what makes fan-out manageable. Because each destination has its own filter, a single busy source feed can supply many systems while each receives only the slice it should. Without filtering, every downstream system would have to inspect and discard traffic it never wanted — pushing interface logic back into the endpoints, which is exactly what the engine exists to avoid.
Transformation: the core value
Transformation is where the engine earns its keep, because two systems are almost never configured identically 1. It takes several common forms, usually combined within one channel:
- Field mapping — moving or copying a value from one position to another. The source may carry an identifier in one field while the destination expects it in another, perhaps with a different assigning authority. This builds directly on the v2 segment-and-field structure covered earlier: mapping is reasoning about where a value sits in each system’s layout.
- Code translation — replacing a value from one code set with the equivalent in another, the practical application of the terminology maps from the Terminology Mapping lesson. A sending site’s local code for a result or a patient class is looked up in a crosswalk and rewritten as the standard code the destination uses.
- Restructuring — adding, removing, or reordering segments so the message matches what the destination accepts, including dropping segments a receiver cannot parse.
- Format and standard conversion — translating between standards entirely, such as building a FHIR resource from an inbound v2 message, or the reverse.
- Data-type coercion and defaulting — reformatting a date or numeric value to the destination’s expected form, and supplying a sensible default when a required field arrives empty.
Simple mappings are usually expressed declaratively, but real-world transforms often need scripting inside the engine to handle conditional logic. Whatever the mechanism, a transform should be deterministic: the same input must always produce the same output. Determinism is what makes an interface testable and its behavior reproducible when something later needs to be diagnosed.
Routing: directing the result
Once filtered and transformed, a message must reach the right places. Content-based routing chooses destinations from the message’s own content — its type, originating facility, or order type — rather than from a fixed wiring. Fan-out is the complementary pattern: one inbound message is copied to several destinations, and each copy can carry its own filter and its own transform. The same admission can become a lab feed, a billing record, and a bed-management update, each shaped differently, from a single arrival.
A worked scenario
Consider one inbound ADT (admit/discharge/transfer) message announcing an admission. The lab channel’s filter passes it because the message type is relevant. A transform then translates the patient-class code — the source’s local value rewritten to the standard code the lab expects — and remaps a local order-related code through a terminology crosswalk. Routing fans the message out: the transformed copy goes to the lab system, while a separately transformed copy, carrying only the fields billing needs, goes to billing. One message in; two correctly shaped messages out, to two systems that never had to learn about each other.
Why this lives in the engine
Every one of these functions could, in principle, be built into the connected applications. The reason they live in the engine is that the engine absorbs the mismatches between systems so that neither endpoint has to change 1. The lab does not need to understand the registration system’s local codes; the billing system does not need to know the admitting feed’s field layout. Each system speaks only its own dialect, and the channel translates. Concentrating filtering, transformation, and routing in one configurable hub is what lets an organization connect systems it does not control — and keep connecting new ones — without reopening software it cannot change.
References
- Tim Benson, Grahame Grieve. Principles of Health Interoperability: FHIR, HL7 and SNOMED CT. 4th ed. Springer. 2021. verified