Enterprise Integration Patterns with Real Examples
A shared vocabulary of patterns solves the same integration problem every decade.

Organizations manage hundreds of applications, and less than a third of them talk to each other. That's the actual state of enterprise IT, and it's why integration patterns aren't some dusty computer science relic. They're the load-bearing walls of every functioning tech stack you've ever used without knowing it.
The pattern repeats no matter what decade you're standing in. Mainframe teams wrote COBOL copybooks to bridge record formats that had no business being compatible. SOA teams built XML transformations to get web services talking. Cloud teams do the same thing now with JSON across REST APIs and SaaS platforms that were never designed to share a room. Now it's microservices, event streams, and AI agents that need to coordinate without being welded together. Same problem, new outfit.
What does the fragmentation actually cost? Data silos that quietly stall digital transformation projects, plus engineers rebuilding the same connector for the third time this year because nobody documented the first one. It's the kind of slow leak that drains a budget over several quarters without ever triggering an alarm. And the enterprise application integration market hit $17.54 billion in 2025, which tells you this isn't a boutique concern for people who like org charts. It's a real industry, solving a real, recurring headache.
The reason the headache recurs is structural, not incidental. Systems that weren't built together don't talk the same language, full stop, and that's exactly why a shared vocabulary of patterns emerged. Once you can name the problem, you can actually solve it instead of reinventing it every budget cycle.
What Hohpe and Woolf actually gave the industry in 2003
Gregor Hohpe and Bobby Woolf wrote the book, literally, in 2003: Enterprise Integration Patterns. Before that book, every shop had its own private jargon for the same five problems. Hohpe and Woolf gave the industry common nouns: message, channel, router, transformer, endpoint. Words that mean the same thing whether you're running IBM middleware or a homegrown Python script duct-taped to a cron job.
The catalogue holds 65 patterns, sorted into buckets: Messaging Channels, Message Construction, Message Routing, Message Transformation, Message Endpoints, and System Management. That's a lot to absorb at once, so don't try. The point isn't memorizing all 65, but understanding that each one describes what needs solving and why, independent of which vendor's product does it, and that's what makes them portable.
Here's the proof: the same five or six patterns show up in mainframes, in SOA, in cloud APIs, and in cloud-native microservices. Technology keeps getting rebuilt from scratch every decade, yet the problems it's solving, apparently, do not. That's evidence the patterns describe something real about how systems relate to each other, independent of whatever's fashionable in tech that year.
So let's walk through them, one at a time, each one anchored to a scenario you'd actually recognize.
Point-to-Point integration and why its simplicity becomes a liability
Point-to-point is exactly what it sounds like. System A talks directly to System B, with no middleman and no abstraction layer, nothing fancy.
Picture a CRM wired directly into an email marketing platform, pushing new leads over as they come in. Two systems, one connection. It works great, and nobody complains, because there's nothing to complain about yet.
Now add a third system. Then a fourth. Then a fifth, because someone in finance insists on a new reporting tool. Each new system needs its own direct wire to every other system it depends on, and the number of connections grows faster than the number of systems does. Each of those wires carries its own error handling, its own assumptions about data format, its own little maintenance chore that somebody has to remember exists.
Here's what that tangle actually looks like on the ground: a mid-sized retailer running separate systems for inventory, point-of-sale, e-commerce, logistics, and finance, every pair wired directly to each other. Nobody on staff can tell you, with confidence, what breaks when the POS system changes its API. That's Tuesday for a lot of retail IT teams.
None of this makes point-to-point wrong. It's appropriately scoped for two systems, but catastrophically under-scoped for twelve.
Hub-and-Spoke and the Enterprise Service Bus: centralization as the first real solution
The fix for point-to-point sprawl is almost embarrassingly obvious once you see it: stop connecting every system to every other system, and connect them all to one central hub instead. The hub routes, transforms, and mediates. Everyone talks to the hub, and nobody has to memorize everyone else's dialect.
Take a large company running separate HR, finance, CRM, and ERP tools, all wired into a central integration hub instead of into each other. When the HR system changes its data format, that gets handled once, at the hub, instead of chasing down every downstream system that happened to be listening.
The Enterprise Service Bus was the SOA era's implementation of this idea, and for a long stretch it was the dominant approach, back when everything an organization ran lived inside its own data center. The ESB gave you centralized routing, transformation, protocol mediation, and logging, all in one place you could actually audit. That's exactly why industries like banking and insurance leaned on it so hard; BFSI led the entire EAI market with a 53.20% share in 2025, and it's not a mystery why. When regulators want to know where every transaction went, "check the hub" beats "check the twelve separate point-to-point wires and hope somebody logged something."
The honest limitation: ESBs are traditionally heavy and on-premises, and they don't flex easily for distributed cloud workloads or microservices teams who want to deploy on their own schedule without asking the ESB team for permission. That's the tension, in a sentence.
Still, don't count the lineage out. IBM's 2023 purchase of Software AG's webMethods and StreamSets, for $2.35 billion, tells you the ESB bloodline still has real enterprise value, even as the architecture around it keeps evolving.
The specific logic that governs how the hub routes, transforms, and recovers messages? That's a set of patterns in its own right, the ones Hohpe and Woolf actually catalogued in detail.
Content-Based Routing: directing messages based on what they contain
A content-based router looks inside an incoming message and sends it wherever it belongs, based on what it finds — what it actually says, rather than who sent it or what channel it arrived on.
An insurance company receiving claims is the textbook case. A property claim goes to one processing service, a medical claim to another, a liability claim to a third, and all three arrive on the exact same inbound channel. The router reads the contents and dispatches accordingly.
This buys you more than routing convenience; it buys you resilience. When a downstream service goes down or gets overloaded, the router can shift traffic to a fallback path or hold it in a queue, so failure in one lane doesn't take down the whole highway. A payment processor does this constantly: high-value transactions get routed to a stricter fraud-check path, low-value ones get the faster lane, same inbound event, two very different treatments downstream.
What the pattern doesn't solve is the format problem. It assumes the message already arrives in something the router can actually parse, which is exactly where translation enters the picture.
The Message Translator: handling the format mismatch that has always existed
This is the oldest problem in the book, literally. System A produces data one way, System B expects it a different way, and that gap has existed since COBOL copybooks and hasn't gone anywhere in the age of XML-to-JSON conversion.
A Message Translator sits in the middle and converts structure, format, or vocabulary so the receiving system understands what it's getting without lifting a finger. A CRM sends customer records as XML; the ERP that processes orders wants JSON. The translator intercepts, converts, forwards. Neither system needs to know the other one exists, which is sort of the whole point.
There's a second layer here that's easy to miss: semantic translation, not just syntax. System A calls a field "customerid," while System B calls the exact same data "accountnumber." Same information, different name tag, and this kind of mismatch shows up constantly after mergers and acquisitions, when two companies' systems suddenly need to exchange data and nobody agreed on terminology beforehand.
Here's the practical catch: Message Translators are rarely a one-and-done build. They accumulate as the system landscape grows, one translator per new integration, which is a decent argument for managing them centrally rather than burying a copy inside every consuming service.
Routing and translating handles the happy path. What happens when a message just doesn't make it?
Guaranteed Delivery and the Dead Letter Channel: what happens when messages fail
Networks go down. Downstream services crash, and messages arrive malformed, or processing times out mid-flight. Any one of these can make a message vanish without a trace, which is a genuinely bad thing to happen to, say, a wire transfer.
Guaranteed Delivery is the sender's assurance that a message reaches its destination eventually, even if the receiver is temporarily out to lunch. The usual implementation is a persistent message store: the message gets written to durable storage before anyone acknowledges receipt, so a crash mid-flight doesn't erase it. A bank's payment instruction has to reach the settlement system, and a brief network hiccup along the way shouldn't mean the transfer simply never happens.
The Dead Letter Channel handles a different failure: the message that genuinely cannot be processed. Wrong format, missing field, a business rule it violates. Instead of silently dropping it into the void, it gets moved to a dead letter queue for inspection, alerting, and either manual or automated retry. A fintech startup running microservices routes failed transaction events to a dead letter channel specifically so no payment disappears quietly; the ops team can go look at what landed there and reprocess it.
Put Guaranteed Delivery and Dead Letter Channels together and you get a full audit trail: every message that entered the system can be accounted for, start to finish. That maps directly onto GDPR, HIPAA, and SOX requirements, which is not a small thing if you're the person who has to explain the audit to a regulator.
These patterns handle one message at a time. Plenty of real processes need several responses gathered together before anything can move forward.
The Aggregator: collecting partial results before the process can continue
An Aggregator collects a set of related messages, or service responses, and merges them into one consolidated message once some completion condition is met.
Take an e-commerce order fulfillment system that needs three things confirmed before it'll ship anything: inventory availability, payment authorization, and a fraud check. The Aggregator holds onto whatever partial results come in and only releases the consolidated response once all three have shown up.
The real design decision is what "done" means. All responses received? Enough responses within a time window? First valid response wins? Each of those produces genuinely different business logic, and picking wrong means either shipping too fast or waiting forever.
And waiting forever is a real risk, because what happens when one response never arrives at all? The Aggregator needs a timeout and a fallback, which ties it right back to Guaranteed Delivery and the Dead Letter Channel as partners in the same job. Combine the Aggregator with content-based routing and you get real resilience under disruption: the router sends requests down alternative paths, and the aggregator just grabs whichever response shows up first. Two patterns, working together, covering for each other's blind spots.
Everything so far has lived in a request/response world, or a fire-and-forget one. There's a different architecture entirely that skips the direct relationship altogether.
Publish-Subscribe: decoupling producers from consumers at the architecture level
A publisher emits a message to a topic or event bus without knowing or caring who's listening. One or more subscribers independently pick it up and do whatever they need to do with it. That's the whole pattern, and it's a bigger deal than it sounds.
What decoupling buys you, in practice: the publisher never waits for an acknowledgment, adding a new subscriber requires zero changes to the publisher, and subscribers can be added, removed, or scaled up entirely on their own schedule.
An online order is the classic case. A customer checks out, a single "OrderPlaced" event fires, and inventory management, payment processing, fraud detection, and shipping label generation all subscribe and react independently. Nobody sits in the middle orchestrating all four; they just each do their job when the event shows up.
Netflix runs this at genuine production scale on Apache Kafka. Its content-finance reporting services publish finance events to Kafka topics, and downstream microservices process them near real time, with keyed messages preserving event ordering and UUID tracking making sure nothing gets lost along the way. This is how a company with hundreds of millions of subscribers keeps its books straight.
And pub-sub is already the dominant model, not a future-facing idea: 85% of global businesses have already adopted event-driven architecture to meet their needs.
The tradeoff is real, though: observability gets harder. When a publisher fires an event and something breaks three services downstream, tracing that failure back to its source takes distributed logging and correlation IDs, work that a plain point-to-point connection never asked you to do.
Pub-sub is the broadcast model. Sometimes, though, you genuinely need a synchronous back-and-forth, and the two coexist in nearly every real system you'll touch.
Request-Reply over messaging infrastructure: when you need a response before continuing
Request-Reply means the sender publishes a request to a channel and waits for a reply on a designated reply channel before moving forward. Synchronous behavior, riding on asynchronous plumbing underneath.
Some operations simply can't proceed without a confirmed answer. You don't approve a loan before the credit check comes back, and you don't confirm an order before you know the item's actually in stock. A loan origination system sends a "CreditCheckRequest" to a scoring service through a message queue; the scoring service drops a "CreditCheckReply" onto a correlated reply channel; the origination system only picks back up once that reply lands.
The detail that makes this actually work at scale is the correlation ID, a unique tag attached to the request and echoed back on the reply, so the sender can match answers to questions even when hundreds of requests are in flight at once. Skip that step and you've got replies arriving with no idea which request they belong to, which is its own kind of chaos.
How does this differ from just calling a REST API directly? Both give you synchronous behavior from the caller's point of view, but Request-Reply over messaging adds durability: the request doesn't vanish if the scoring service happens to be down when it arrives, it just waits in the queue. And neither service needs to know the other's network address, which matters more than it sounds like once you're running dozens of services that get redeployed on their own schedules.
API-led connectivity as a three-tier architecture for organizing integration at scale
Every pattern above solves one specific, recurring headache. API-led connectivity is the architecture that organizes all of them into something a whole company can actually run on, rather than a pile of point solutions nobody fully owns.
The model splits into three layers. System APIs sit closest to the actual data sources, the databases and legacy platforms and SaaS tools, and expose their data in a consistent way regardless of what's underneath. Process APIs sit above that, combining and orchestrating data from multiple System APIs to represent an actual business process, like "get everything needed to fulfill an order." Experience APIs sit on top, shaping that data for whatever's consuming it: a mobile app, a partner's website, an internal dashboard.
The genuine payoff is reuse. Build a System API once, against the ERP, and every Process API that needs order data calls that same layer instead of every team writing its own direct connector into the ERP and hoping it doesn't break next quarter. That's point-to-point sprawl, solved by architecture instead of by hoping people communicate better. This is Hub-and-Spoke's insight, generalized: centralize the connection points, let everything else build on top of a stable, documented layer instead of reaching straight into the source system.
It also plays well with everything covered above, rather than replacing it. Content-Based Routing and Message Translators live comfortably inside System and Process APIs. Publish-Subscribe operates alongside API-led connectivity rather than against it, plenty of shops run event streams for the fire-and-forget cases and APIs for the ones that need a defined contract and a synchronous answer. The patterns are the vocabulary. API-led connectivity is one common way of arranging that vocabulary into something a hundred engineering teams can build on without stepping on each other.
That's the throughline across two decades of relabeled technology: the tools change every few years, the problems barely move, and the patterns that solve them turn out to be worth learning once and reusing forever.


