Enterprise integration pattern diagrams

Routers, splitters, aggregators, dead letters: messaging made legible.

The Hohpe and Woolf integration patterns, drawn with their standard icons. These matter because messaging systems fail in ways that are almost impossible to describe in prose: a splitter without an aggregator, a wire tap that changes ordering, a dead letter queue nobody drains.

When to use these

When not to

Common mistakes

The pattern people skip is the dead letter path, and it is the one that causes the 3am page. If your integration diagram has no error route, it is a happy-path sketch rather than a design.

The 8 templates

Simple Messaging.puml

A channel and two endpoints: the vocabulary in miniature.

Simple Messaging: rendered example
Show the source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/EIP-PlantUML/main/dist/EIP-PlantUML.puml

title Simple Messaging Flow

LAYOUT_LEFT_RIGHT()

MsgChannel(input, "Input Channel")
MessageFilter(filter, "Filter")
MessageTranslator(translator, "Translator")
MsgChannel(output, "Output Channel")

Send(input, filter)
Send(filter, translator)
Send(translator, output)

@enduml

Notes and a copy button for this template

Content-Based Router.puml

Route by message content. Where most integrations start.

Content-Based Router: rendered example
Show the source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/EIP-PlantUML/main/dist/EIP-PlantUML.puml

title Content-Based Routing

MsgChannel(input, "Incoming Orders")
ContentBasedRouter(router, "Order Router")

MsgChannel(domestic, "Domestic Orders")
MsgChannel(international, "International Orders")
MsgChannel(priority, "Priority Orders")

ServiceActivator(domesticSvc, "Domestic\nFulfillment")
ServiceActivator(intlSvc, "International\nFulfillment")
ServiceActivator(prioritySvc, "Priority\nFulfillment")

Send(input, router)
router --> domestic : country = US
router --> international : country != US
router --> priority : priority = HIGH

Send(domestic, domesticSvc)
Send(international, intlSvc)
Send(priority, prioritySvc)

The rest of this template, and how to use it

Publish-Subscribe.puml

One publisher, many independent subscribers.

Publish-Subscribe: rendered example
Show the source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/EIP-PlantUML/main/dist/EIP-PlantUML.puml

title Publish-Subscribe Pattern

MessagingGateway(publisher, "Event Publisher")
PubSubChannel(topic, "Order Events")

DurableSubscriber(inventory, "Inventory Service")
DurableSubscriber(shipping, "Shipping Service")
DurableSubscriber(billing, "Billing Service")
NonDurableSubscriber(analytics, "Analytics Service")

Send(publisher, topic)
Send(topic, inventory)
Send(topic, shipping)
Send(topic, billing)
Send(topic, analytics)

@enduml

Notes and a copy button for this template

Splitter-Aggregator.puml

Split a message, process the parts, put them back together.

Splitter-Aggregator: rendered example
Show the source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/EIP-PlantUML/main/dist/EIP-PlantUML.puml

title Splitter-Aggregator Pattern

LAYOUT_LEFT_RIGHT()

MsgChannel(input, "Batch Orders")
Splitter(splitter, "Order Splitter")
MsgChannel(items, "Individual Items")

ServiceActivator(process1, "Process Item")
ServiceActivator(process2, "Process Item")
ServiceActivator(process3, "Process Item")

MsgChannel(processed, "Processed Items")
Aggregator(aggregator, "Order Aggregator")
MsgChannel(output, "Complete Orders")

Send(input, splitter)
Send(splitter, items)

Send(items, process1)
Send(items, process2)

The rest of this template, and how to use it

Pipes and Filters.puml

A processing chain where each stage is replaceable.

Pipes and Filters: rendered example
Show the source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/EIP-PlantUML/main/dist/EIP-PlantUML.puml

title Pipes and Filters Pattern

LAYOUT_LEFT_RIGHT()

ChannelAdapterLeft(source, "File\nAdapter")
MsgChannel(ch1, "")

Filter(decrypt, "Decrypt")
MsgChannel(ch2, "")

Filter(authenticate, "Authenticate")
MsgChannel(ch3, "")

Filter(validate, "Validate")
MsgChannel(ch4, "")

Filter(transform, "Transform")
MsgChannel(ch5, "")

ChannelAdapterRight(sink, "Database\nAdapter")

The rest of this template, and how to use it

Request-Reply.puml

Async messaging that still needs an answer.

Request-Reply: rendered example
Show the source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/EIP-PlantUML/main/dist/EIP-PlantUML.puml

title Request-Reply Pattern

MessagingGateway(client, "Client Application")

P2PChannel(requestChannel, "Request Channel")
P2PChannel(replyChannel, "Reply Channel")

ServiceActivator(service, "Order Service")

RequestReply(request, "Order Request")
Message(reply, "Order Response")

Send(client, request)
Send(request, requestChannel)
Send(requestChannel, service)
Send(service, reply)
Send(reply, replyChannel)
Send(replyChannel, client)

note right of request
  Contains:

The rest of this template, and how to use it

Error Handling.puml

What happens when a message cannot be processed. Draw this one.

Error Handling: rendered example
Show the source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/EIP-PlantUML/main/dist/EIP-PlantUML.puml

title Error Handling with Dead Letter Channel

MsgChannel(input, "Incoming Messages")
MessageRouter(router, "Message Router")

MsgChannel(valid, "Valid Messages")
InvalidMsgChannel(invalid, "Invalid Messages")
DeadLetterChannel(dlq, "Dead Letter Queue")

ServiceActivator(processor, "Message Processor")
ServiceActivator(errorHandler, "Error Handler")
MessageStore(store, "Message Store")

Send(input, router)
router --> valid : valid
router --> invalid : invalid format
Send(valid, processor)
processor --> dlq : processing error
Send(invalid, dlq)
Send(dlq, errorHandler)
Send(errorHandler, store)

The rest of this template, and how to use it

Wire Tap (Monitoring).puml

Observe traffic without changing it: for audit and monitoring.

Wire Tap (Monitoring): rendered example
Show the source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/EIP-PlantUML/main/dist/EIP-PlantUML.puml

title Wire Tap for Monitoring

LAYOUT_LEFT_RIGHT()

MsgChannel(input, "Orders")
WireTap(tap, "Wire Tap")

MsgChannel(main, "Main Flow")
MsgChannel(monitor, "Monitor Flow")

ServiceActivator(processor, "Order Processor")
MessageStore(audit, "Audit Log")

Send(input, tap)
Send(tap, main)
Send(tap, monitor)
Send(main, processor)
Send(monitor, audit)

@enduml

Notes and a copy button for this template

Render these offline

Every template here ships in Gnomon and renders on your machine, with no account and nothing sent to a server. The browser editor is free and needs no install.

Get GnomonOpen the browser editor