Splitter
A Splitter decomposes a composite message into one message per element, enabling independent and parallel per-item processing. It typically tags each part with correlation and sequence data so an Aggregator can later reassemble them.
A Splitter takes a single message that contains a collection of elements and emits one message per element. It decomposes a batch or composite document so that downstream components can handle each item independently, often in parallel.
The problem it solves is granularity mismatch. A producer may send a large order with many line items, a file with many records, or a batch with many transactions, while downstream processing is defined per item. The splitter bridges this gap by fanning a composite into its constituent parts.
How It Works
The splitter parses the incoming message to identify its elements, then publishes a new message for each. To allow later reassembly, it typically attaches correlation metadata: a shared correlation identifier so a downstream Aggregator can group the parts, a sequence number for ordering, and often a total count so the aggregator knows when it has them all.
Splitters may be iterating (walk a list) or static (split fixed substructures). They pair naturally with the aggregator to form the split-process-aggregate idiom, the messaging analogue of map-reduce.
[ order: {items:[A,B,C]} ] --> [Splitter] --> msg(A) msg(B) msg(C)
(each tagged with correlationId + sequence + total=3)
When to Use It
Use it when an incoming message bundles items that should be processed separately, when you want to parallelize per-item work, or when downstream services accept only single records. It is common in file ingestion, batch processing, and order-fulfillment pipelines.
Avoid splitting when items must be processed atomically as a unit, or when the overhead of many small messages outweighs the benefit.
Trade-offs
Splitting increases message volume and infrastructure load, and it raises the question of reassembly: if parts must later recombine, you need correlation and an aggregator, which adds state and timeout handling. Error handling becomes per-item, which is more granular but more complex. The payoff is parallelism and the ability to apply per-item routing, enrichment, and retries.
Related Patterns
The Aggregator is its inverse, recombining parts. A Resequencer restores order after parallel processing. A Content Enricher often runs on each split element. Composing splitter and aggregator yields scatter-gather-style processing.
Example
Apache Camel's split(body().tokenize("\n")) reads a CSV file message and emits one message per line, allowing each record to be validated, transformed, and persisted independently, with a correlation id linking them back to the source file.