Mule Event Structure: Payload, Attributes, Variables Explained
This post closes out Phase 2 of our beginner series by explaining exactly what data looks like as it flows through a Mule application. If you've been following along, you've already used a payload without formally defining it — this post makes that (and two other key concepts) precise, because getting this right early saves a lot of confusion once you start writing DataWeave scripts.
The Mule Event
Every time a flow runs — triggered by an HTTP request, a scheduled timer, a file arriving — Mule creates a Mule Event. This event is the container that carries data through every step of the flow, from the source all the way to the final processor.
This was one of the biggest simplifications MuleSoft made moving from Mule 3 to Mule 4 (covered in an earlier post in this series) — the Mule Event has a clean, consistent structure made of exactly three parts:
Mule Event
├── Payload — the actual data
├── Attributes — metadata about the payload
└── Variables — custom data you set yourself
Let's go through each one.
1. Payload
The payload is the main data itself — the thing your flow is actually working with. It changes shape constantly as data moves through a flow: it might start as raw JSON from an HTTP request, get transformed into a different structure by a Transform Message step, then get transformed again before being sent to a database.
In the "Hello World" example from earlier in this series, the payload after your Transform Message step was:
{ "message": "Hello World" }
Key mental model: at any given point in a flow, ask "what is the payload right now?" — because every processor typically reads from (and often replaces) the current payload.
You reference the payload in DataWeave using payload:
%dw 2.0
output application/json
---
payload
2. Attributes
Attributes are metadata about the payload — information describing where it came from or its context, without being part of the actual data itself.
The exact attributes available depend on the connector that produced the event. For example:
- An HTTP Listener source populates attributes with things like the request's HTTP method, headers, query parameters, and URI
- A File connector reading a file populates attributes with things like the file name, size, and last-modified timestamp
- A Database connector's results might include attributes about the query that was run
This is one of the genuinely nice things about Mule 4's design: attributes are always structured the same way (accessible via attributes in DataWeave), regardless of which connector produced them — you don't need to learn a different metadata structure for every connector type.
Example — reading a query parameter from an HTTP request:
%dw 2.0
output application/json
---
{
requestedName: attributes.queryParams.name
}
3. Variables
Variables are custom values you explicitly set during a flow, to store something you'll need later — completely separate from the payload and attributes, which are set automatically by connectors.
A common beginner use case: you fetch a customer ID early in a flow, but need it several steps later after the payload has already changed shape multiple times. Rather than trying to preserve it inside a changing payload, you store it in a variable.
You set a variable using the Set Variable component (mentioned in the previous post):
- Variable Name:
customerId - Value: (a DataWeave expression, e.g.
payload.id)
And reference it anywhere later in the flow using vars.customerId:
%dw 2.0
output application/json
---
{
customer: vars.customerId
}
Putting the Three Together: A Worked Example
Imagine a flow that receives an HTTP request to look up a customer:
- HTTP Listener (source) — request comes in with a query parameter
?id=123 - Set Variable — store
vars.customerId = attributes.queryParams.id - Database Select — query the database using
vars.customerId; the payload now becomes the query result - Transform Message — build the final JSON response using the payload (query result) and maybe
vars.customerIdagain for confirmation
Notice how all three concepts work together: attributes gave us the incoming ID, a variable preserved it across steps where the payload kept changing, and the payload carried the actual data being transformed at each stage.
Quick Reference Table
| Concept | What it is | How to access in DataWeave | Set automatically or manually? |
|---|---|---|---|
| Payload | The main data | payload |
Set/replaced by processors as data moves through |
| Attributes | Metadata about the payload | attributes |
Set automatically by the source connector |
| Variables | Custom values you store | vars.yourVariableName |
Set manually via Set Variable |
Why This Matters Going Forward
Every single DataWeave script you'll ever write references some combination of payload, attributes, and vars. Getting this model solid now means the next phase of this series — a deep dive into DataWeave itself — will click far faster, since you already understand exactly what data you're transforming and where it comes from.
Phase 2 Complete
That wraps up Phase 2: Getting Started — you've installed Anypoint Studio, toured Anypoint Platform, built your first flow, and now understand the core building blocks (flows, sub-flows, message processors) and the Mule Event structure underneath everything.
Coming up in Phase 3: a deep dive into DataWeave — starting with DataWeave 2.0 fundamentals, the single highest-leverage skill in all of MuleSoft development.
0 Comments