I replaced a 40-line if/else chain with 4 match/case lines last month. Then I forgot the else clause and 3,000 production events backed up.
TL;DR
-
match/casereplaces nested if/else with value matching, guard conditions, and type dispatch - Missing
elseclause causes runtime errors on unmatched values — unlike switch/default, there's no implicit fallthrough -
event.typefails —typeis a reserved word in DataWeave, useevent."type"with quotes - Guard conditions (
case t if t startsWith "payment.") handle wildcard matching
The Problem: Growing If/Else Chains
We had an event routing flow. Orders, payments, user actions — each type needed a different processing queue:
if (event."type" == "order.created") { category: "ORDER", action: "PROCESS" }
else if (event."type" == "order.cancelled") { category: "ORDER", action: "REFUND" }
else if (event."type" == "payment.received") { category: "PAYMENT", action: "RECONCILE" }
else if (event."type" == "payment.refunded") { category: "PAYMENT", action: "RECONCILE" }
else if (event."type" == "user.login") { category: "CUSTOMER", action: "SYNC" }
else if (event."type" == "user.logout") { category: "CUSTOMER", action: "SYNC" }
else if (event."type" == "user.signup") { category: "CUSTOMER", action: "ONBOARD" }
else { category: "SYSTEM", action: "LOG" }
40 lines. Growing every sprint. Hard to read. Repetitive.
The Fix: match/case
%dw 2.0
output application/json
fun routeEvent(event: Object): Object =
event."type" match {
case "order.created" -> ({ category: "ORDER", action: "PROCESS", priority: "NORMAL" })
case "order.cancelled" -> ({ category: "ORDER", action: "REFUND", priority: "HIGH" })
case eventType if eventType startsWith "payment." -> ({ category: "PAYMENT", action: "RECONCILE", priority: "HIGH" })
else -> ({ category: "SYSTEM", action: "LOG", priority: "LOW" })
}
---
payload.events map (event) -> routeEvent(event)
4 cases. Value matching for exact types. Guard condition for the payment prefix. Else for everything unexpected.
100 production-ready DataWeave patterns with tests: mulesoft-cookbook on GitHub
Trap 1: The Missing Else Clause
I deployed my first version without else. For 3 weeks, every event was a known type. Then an "inventory.updated" event arrived — a type I hadn't handled.
Runtime error. 3,000 events backed up in the queue before monitoring caught it.
DataWeave's match/case does NOT have implicit fallthrough. Without else, an unmatched value throws an exception. Unlike JavaScript's switch where falling through is the default, DataWeave requires explicit handling of every possible value.
Rule: every match block needs an else clause. No exceptions.
Trap 2: Reserved Word Field Access
event.type // PARSE ERROR — "type" is a reserved word
event."type" // works — quoted field name
DataWeave reserves type as a keyword. When your JSON has a type field (which is extremely common in event-driven architectures), you must quote it in the selector. I spent 20 minutes debugging this the first time.
Other reserved words that break field selectors: match, case, if, else, do, fun, var, type, input, output.
Guard Conditions: Pattern Matching with Logic
The case eventType if eventType startsWith "payment." syntax combines pattern matching with boolean guards:
event."type" match {
case t if t startsWith "order." -> handleOrder(t)
case t if t matches /user\.(.*)/ -> handleUser(t)
case t if sizeOf(t) > 50 -> handleLongType(t)
else -> handleUnknown()
}
You can use any boolean expression after if. The bound variable t holds the matched value for use in both the guard and the result.
What I Do Now
- Every match block has an else clause before deployment
- Reserved word fields always use quoted selectors
- New event types go into the match block proactively — I review dead-letter queue weekly
- Code reviews flag match without else as a blocking issue
100 patterns with MUnit tests: github.com/shakarbisetty/mulesoft-cookbook
60-second video walkthroughs: youtube.com/@SanThaParv
Top comments (0)