Mule 4 - How to Iterate over Map Entries
Mule 4 uses DataWeave as its expression and transformation language. Iterating over a list is straightforward with the <foreach> component, but a common question is how to apply the same pattern when the payload is a Map rather than a List.
The key is to convert the Map into a collection that For Each can iterate over. DataWeave's entrySet function provides the Map entries as key-value pairs, allowing each entry to be processed individually inside the For Each scope.
For differences in For Each behavior when migrating from Mule 3 to Mule 4, see the MuleSoft migration documentation.
Example
The following Mule configuration demonstrates the complete approach:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw"
xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:mspring="http://www.mulesoft.org/schema/mule/spring"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.mulesoft.org/schema/mule/spring http://www.mulesoft.org/schema/mule/spring/current/mule-spring.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
<http:listener-config name="HTTP_Listener_config">
<http:listener-connection host="localhost" port="8081" />
</http:listener-config>
<flow name="foreachDemo">
<http:listener config-ref="HTTP_Listener_config" path="foreach"/>
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
id: '12345',
firstName: 'FName',
lastName: 'LName'
}
]]>
</ee:set-payload>
</ee:message>
</ee:transform>
<logger level="INFO" message="JSON Payload to iterate: #[payload]" />
<foreach collection="#[dw::core::Objects::entrySet(payload)]">
<logger level="INFO" message="Inside foreach: #[payload]" />
</foreach>
</flow>
</mule>Output
The flow iterates over each Map entry and produces the following output:
INFO 2018-06-18 09:15:18,833 [[MuleRuntime].cpuLight.07: [dummy].foreachDemo.CPU_LITE @4b36449b] [event: 0-c0aa57b0-737f-11e8-9d25-34363b68f902] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: JSON Payload to iterate: {
"id": "12345",
"firstName": "FName",
"lastName": "LName"
}
INFO 2018-06-18 09:15:20,082 [[MuleRuntime].cpuLight.07: [dummy].foreachDemo.CPU_LITE @4b36449b] [event: 0-c0aa57b0-737f-11e8-9d25-34363b68f902] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Inside foreach: {
"key": "id",
"value": "12345",
"attributes": null
}
INFO 2018-06-18 09:15:20,089 [[MuleRuntime].cpuLight.07: [dummy].foreachDemo.CPU_LITE @4b36449b] [event: 0-c0aa57b0-737f-11e8-9d25-34363b68f902] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Inside foreach: {
"key": "firstName",
"value": "FName",
"attributes": null
}
INFO 2018-06-18 09:15:20,094 [[MuleRuntime].cpuLight.07: [dummy].foreachDemo.CPU_LITE @4b36449b] [event: 0-c0aa57b0-737f-11e8-9d25-34363b68f902] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Inside foreach: {
"key": "lastName",
"value": "LName",
"attributes": null
}Takeaway
When a Mule 4 flow needs to iterate over a Map, use DataWeave's entrySet function to expose the entries as an iterable collection. This keeps the flow simple while preserving access to both the key and value for each Map entry.