Back to course overview
4
Module 4 of 7

DataWeave 2.0 Mastery

Go deep on DataWeave 2.0 — the language that powers all data transformation in Mule 4. Covers types, core functions, format conversion, and real-world examples.

4 lessons~5 hours
1

Types, Variables & Core Operators

DataWeave is a strongly typed, expression-oriented language. Everything is an expression that returns a value.

DataWeave supports String, Number, Boolean, Date, DateTime, Object, Array, Null, and Binary types. All types are immutable — transformation always produces new values.

Variables declared with `var` are immutable bindings. Functions are first-class values. The `->` syntax defines anonymous functions (lambdas).

The `++` operator concatenates strings, arrays, and objects. The `update` operator creates a modified copy of an object without mutation.

Type coercion and variable bindingdataweave
%dw 2.0
output application/json

var today    = now() as Date
var greeting = "Hello, " ++ payload.name ++ "!"
var taxRate  = 0.08 as Number

---
{
  message:    greeting,
  reportDate: today as String { format: "yyyy-MM-dd" },
  netAmount:  payload.amount,
  tax:        (payload.amount * taxRate) as Number { format: "0.00" },
  total:      (payload.amount * (1 + taxRate)) as Number { format: "0.00" }
}
2

map, filter, reduce & groupBy

The four most important higher-order functions for working with arrays in DataWeave.

`map` transforms every element of an array. `filter` keeps only elements matching a predicate. `reduce` folds an array into a single accumulated value. `groupBy` partitions an array into a keyed object.

These functions compose naturally. A common pattern is to filter first (to remove unwanted items), then map (to reshape), then reduce (to aggregate) — forming a pipeline with no intermediate variables.

All four functions receive the element and its index as arguments: `(item, index) ->`. Only using `item`? DataWeave lets you omit the index parameter entirely.

Chaining map, filter, reduce, groupBydataweave
%dw 2.0
output application/json
---
// Group active orders by customer, summing each customer's total
(payload
  filter (o) -> o.status == "active"
  groupBy (o) -> o.customerId)
mapObject ((orders, customerId) -> {
  (customerId): {
    orderCount: sizeOf(orders),
    totalAmount: orders reduce ((acc = 0, o) -> acc + o.amount)
  }
})
3

Format Conversion: JSON, XML, CSV

DataWeave treats all formats uniformly through its canonical data model — conversion is a header declaration away.

The `input` and `output` directives control the source and target formats. When Mule passes a payload of a given MIME type, DataWeave automatically selects the correct reader. You only need an explicit `input` directive when the type cannot be inferred.

XML namespaces require special handling. Use the `ns` declaration to bind a prefix to a URI, then reference it in path expressions with `ns#elementName`.

CSV requires specifying whether the first row is a header (`header=true`). The separator defaults to comma but can be overridden.

CSV input → JSON outputdataweave
%dw 2.0
input payload application/csv header=true separator=","
output application/json
---
payload map (row) -> {
  id:       row.employee_id as Number,
  name:     row.full_name,
  dept:     row.department,
  salary:   row.salary as Number,
  joinDate: row.join_date as Date { format: "MM/dd/yyyy" }
}
JSON input → XML output with namespacedataweave
%dw 2.0
output application/xml
ns ns0 http://acme.com/orders/v1
---
{
  ns0#OrderEnvelope: {
    ns0#Header: {
      ns0#Version: "1.0",
      ns0#Timestamp: now() as String { format: "yyyy-MM-dd'T'HH:mm:ss" }
    },
    ns0#Orders: {
      (payload.orders map (o) -> {
        ns0#Order @(id: o.orderId): {
          ns0#Customer: o.customer,
          ns0#Amount:   o.amount
        }
      })
    }
  }
}
4

Real-World DataWeave Patterns

Patterns you will encounter in every production MuleSoft project.

Flattening nested structures, merging payloads from multiple sources (using `vars`), default values with `default`, conditional fields with `if`, and dynamic key names with `(expression): value` — these cover 90% of real transformation requirements.

When working with large payloads, use `pluck` to convert an object to an array of key-value pairs, and `zip` / `unzip` to work with paired arrays.

The `@` syntax attaches XML attributes to elements. For JSON, use it to add metadata fields dynamically based on runtime conditions.

Merging payload + variable + conditional fieldsdataweave
%dw 2.0
output application/json
var enrichment = vars.customerProfile default {}
---
payload map (order) -> {
  orderId:     order.id,
  customer:    enrichment.name default order.customerId,
  tier:        enrichment.tier default "standard",
  amount:      order.total,
  currency:    order.currency default "USD",
  (discount:   enrichment.discountPct) if enrichment.discountPct?,
  processedAt: now() as String
}