SAP CI Routers: Choose Your Own Adventure (Some Choices are Better Than Others)
- David Morin
- Mar 4
- 3 min read
Intro
Let’s do a more technical blog. Today, we’re talking about Routers in SAP Cloud Integration. Routers are incredibly powerful tools, but if you’re coming from a SAP PO background, there is some nuance that is worth discussing.
The Router

The PO Approach
PO, going all the way back to XI, used the XI-Pipeline:
· Adapter
· Sender Agreement
· Receiver Determination
· Interface Determination
· Receiver Agreement
· Adapter
It’s structured. Predictable. Constrained.
Routing logic lived on the receiver and interface determination and was XPATH based (Outside NW BPM, which has a similar router concept).
While In PO, routing was part of the pipeline, in CI, the pipeline is optional and the interfaces are more free-flowing and flexible.
SAP CI Routers
In CI, routers are branching mechanisms inside an integration process. With an SAP CI router you can:
Perform content-based routing (e.g., fetch a new API key if the current one is expired), and continue processing
Gracefully end a process based on data- Validation
Make conditional calls within a single integration process
Route on XML (XPath)
Route on non-XML conditions (headers/properties)
Breakdown

The Good
Routers add massive flexibility. You’re no longer bound to the XI pipeline model. You can make decisions anywhere in the flow. This is architecturally liberating. It allows for more complex processes and validations, and better handling of end events.
The Ugly (XML)
Let me be clear: I have no issue with XML routers. They are functional.
CI supports XPath 3.1. That’s more capable than PO. You can use regex. You can do powerful logic.
But here’s the honest truth:
Once your XPath goes beyond something simple like:
//field1 = 'ABC'
It becomes hard to read.
Hard to maintain.
Hard for the next developer to guess what the goal was.
Here’s an example from a recently migrated BPM object that needed a router.

This is what it would look like in a router in CI (It wouldn’t work, but just imagine trying to understand this):

Its not easy to read, maintain, and … well I just don’t like it.
Yes it was ugly even in PO, but with the xpath editor and a larger viewing area, it was manageable. On CI, its all on one line. When the logic gets more complex, the readability drops fast and when that happens, it becomes difficult to support. Inevitably, when the logic gets tough, I opt for:
The “Bad” (Meaning: Actually Awesome)
Non-XML Routers
Instead of moving that XPath as-is, I can use a quick script:

Then in the router, its just a non-xml condition and ${header.routeA } = ‘true’
*If we can store a Boolean typed properties it would be ${header.routeA}.
A few advantages to a groovy script setting a header/property for a non-xml router. We can:
Evaluate the complex logic
Set a header or property like routeA = true
Add comments explaining what’s happening
Clean. Obvious. Maintainable. Even for a newbie to groovy.
Finally you can use a little groovy to simplify router into router patterns to avoid iFlows that look like an Atlanta map:

(The Router Gotcha)
In CI, once a router hits a true condition, it executes that path — and it’s done.
It does not continue evaluating the other branches.
Let’s visualize this (I am writing this late at night for reference):

Imagine a router called IceCream with three routes:
1. Vanilla
2. Chocolate
3. Strawberry
If your message was Neapolitan (As shown in the picture), it would only execute vanilla as that condition is evaluated first and returns true.
If you need multiple branches to execute without modifying the source payload via a splitter, you need a
Multicast.
And that’s where things get even more interesting. Honestly, I wanted to do multicasts in this blog, but it just got too long.
Coming Next
In Part 2, we’ll break down Multicasts in CI:
Sequential vs Parallel
When to use each
Performance implications and limitations
Design patterns that avoid common pitfalls
Once you understand the Router + Multicast combination properly, you will stop designing CI flows like PO and start making flows that are easy to read and support, and do what you want.
-------
If you’re migrating from PO to CI:
Are you designing for Cloud Integration instead of recreating XI in the cloud? Always consider:
What’s going to be cleaner and easier to support when you have an issue?




Comments