Skip to content
Kitegra
← Back to the blog

Module in this article: Integration Flow Helper

Camel Simple Expressions in SAP CPI: Headers, Properties and ${…} with Examples

How Camel Simple expressions work in SAP CPI: ${header.x}, ${property.x}, ${in.body}, dates, the Content Modifier order, Router conditions and the mistakes that return nothing.

Camel Simple Expressions in SAP CPI: Headers, Properties and ${…} with Examples

Almost every dynamic value in an SAP Cloud Integration (SAP CPI) iFlow is written in the Simple expression language of Apache Camel: a header in a receiver address, a property in a Content Modifier, a date in a file name, a condition on a Router. The syntax is short, ${…}, and it is easy to get slightly wrong without noticing.

This article covers the expressions you will use every day, the order in which a Content Modifier evaluates them, the difference between headers and exchange properties, and the mistakes that make an expression quietly return nothing.

What a Simple expression is in SAP CPI

SAP Integration Suite runs each iFlow on Apache Camel. When a step runs, Camel replaces every ${…} in the field with a value from the current message: a header, an exchange property, the body, or a built-in function such as the current date. The text around the expression stays as it is, so Order-${header.orderId}.xml becomes Order-4711.xml.

You can write Simple expressions in Content Modifier values of type Expression and in the message body, in the address and query fields of many receiver adapters, in Router and Filter conditions of type Non-XML, and in fields such as a mail subject or an SFTP file name. Externalized parameters look similar but are different: {{receiverHost}} is replaced once, when you deploy the iFlow, while ${…} is evaluated for every message.

The expressions you will use every day

A handful of expressions cover most iFlows, and they mix freely with plain text. A Content Modifier body, for example, can build a whole XML document from headers, properties and functions:

<Order>
  <Id>${property.orderId}</Id>
  <Customer>${header.customerId}</Customer>
  <ReceivedOn>${date:now:yyyy-MM-dd}</ReceivedOn>
  <Flow>${camelId}</Flow>
  <MessageLog>${property.SAP_MessageProcessingLogID}</MessageLog>
</Order>
ExpressionWhat it returns
${header.orderId}The message header orderId
${property.orderId}The exchange property orderId (Camel also accepts ${exchangeProperty.orderId})
${in.body} or ${body}The current message body as text
${date:now:yyyy-MM-dd}Today's date in the given Java date pattern
${camelId}The name of the running integration flow
${property.SAP_MessageProcessingLogID}The ID of the current message processing log
${header.CamelHttpResponseCode}The status code returned by the last HTTP call

How a Content Modifier evaluates headers, properties and the body

A Content Modifier works through its tabs in a fixed order: first the Message Header table, then the Exchange Property table, then the Message Body. Within each table the rows run from top to bottom.

That order decides what an expression can see. A property row can read a header created earlier in the same Content Modifier, and the body can use both. A header row cannot read a property that the same Content Modifier creates, because the property does not exist yet when the header is evaluated; it reads an empty value instead. When you need that, set the property in an earlier Content Modifier, or move the value to the header table above it.

  • Source type Expression: the value is a Simple expression, for example ${date:now:yyyyMMdd}-${header.orderId}.
  • Source type Header or Property: copies another header or property by name, with no ${…} around it.
  • Source type XPath: reads a value from an XML body (see the XPath article linked below).
  • Source types Constant, Local Variable, Global Variable and Number Range cover fixed values and stored values.

Headers or exchange properties: which one to use

A header travels with the message. Receiver adapters can pass headers to the system you call, and headers cross a ProcessDirect call to another iFlow. An exchange property stays inside the current iFlow's exchange and is never sent to a receiver by itself.

Two details cause most surprises. Header names are case-insensitive, so ${header.OrderID} and ${header.orderid} read the same header. Exchange property names are case-sensitive, so ${property.OrderID} and ${property.orderId} are two different properties, and the second one may simply not exist.

  • Use a property for values that only this iFlow needs: IDs, counters, flags, saved copies of the payload.
  • Use a header for values an adapter or the next iFlow must receive, and remove headers that should not leave the tenant.
  • Keep large values out of headers: they travel with every call.

Simple conditions in Router and Filter

In a Router route or a Filter of type Non-XML, the condition is a Simple expression compared with a value. The usual operators are =, !=, >, >=, <, <=, contains, in and regex, joined with and or or. Text values go in single quotes:

${header.orderType} = 'EXPRESS'
${property.amount} > 1000 and ${header.country} in 'DE,AT,CH'
${header.CamelHttpResponseCode} != '200'

If the header or property in a condition does not exist, the condition is simply false and the message takes another route, often the default one. The article on unknown headers and properties shows how to catch that before it reaches production.

How Kitegra helps

The Kitegra is a browser extension for the SAP Integration Suite designer. Type ${ or $ in a designer field and it lists the names that fit at that point of the iFlow: headers and properties set in Content Modifiers, in Groovy and JavaScript scripts and elsewhere in the iFlow, SAP and Camel standard headers and expressions, {{…}} parameters, variables and Data Store names. A name set on only some paths is marked "set on some paths only".

Its lint panel flags an unclosed ${, stray spaces inside an expression, and headers or properties that nothing in the iFlow sets. For XPath rows, a sample payload gives you path suggestions too, as the XPath article explains. It never saves, deploys or edits an iFlow's content, and your tenant changes only when you click one of four named actions, which can be switched off.

To see the values your expressions really produce, trace a message step by step and read the headers and properties before each step.

Without an account it works on 5 iFlows per module. The Free plan covers 50, Starter 100 and Pro 300. On the team plans every member gets Pro, with 300 iFlows per module on Startup Team and no limit on Growth Team and Scale Team. While Kitegra launches, every tool is open to everyone signed in, on the Free plan too. Compare the plans.

Try it in your next iFlow

Read what Kitegra does in the SAP Integration Suite designer, or see it next to its modules.

Frequently asked questions

What is the difference between ${header.x} and ${property.x} in SAP CPI?

${header.x} reads a message header, which travels with the message and can reach receivers and other iFlows. ${property.x} reads an exchange property, which stays inside the current iFlow.

Are header and property names case-sensitive?

Header names are not: ${header.OrderID} and ${header.orderid} read the same header. Exchange property names are, so ${property.OrderID} and ${property.orderId} are different properties.

Why is my header empty when I set it from a property in the same Content Modifier?

A Content Modifier evaluates the header table first, then the property table, then the body. A header cannot read a property created in the same step; set the property in an earlier step.

How do I put today's date into a file name or field?

Use ${date:now:yyyy-MM-dd} with any Java date pattern, for example ${date:now:yyyyMMddHHmmss} for a timestamp.

Is {{parameter}} a Simple expression?

No. {{…}} marks an externalized parameter, replaced once when the iFlow is deployed. ${…} is evaluated by Camel for every message.

What happens if an expression names a header that does not exist?

It returns an empty value without an error, so the problem shows up later as a wrong route or an empty field. A lint check or a guard step catches it earlier.

Work on iFlows without leaving the designer

Add Kitegra to Chrome or Microsoft Edge. Start free, no account needed.