What difference between streaming and non-streaming transformations in mule 4?
In Mule 4, data streaming determines how Mule processes and stores data when reading from or
transforming payloads — especially large ones (like files, database results, or HTTP responses).
⚡ Difference Between Streaming and Non-Streaming Transformations
Aspect Streaming Transformations Non-Streaming Transformations
Process data as a stream, reading and writing it
Load the entire payload into memory
Definition in chunks rather than loading the whole payload
before processing.
into memory.
Low memory footprint — only small portions High memory usage — entire data
Memory Usage
are in memory at any time. must fit in memory.
Slower and memory-intensive for large
Performance (for More efficient and faster for large files or big
payloads — may cause
large data) payloads (like 1GB CSV/JSON).
OutOfMemoryError.
- File Connector (streaming enabled)
- Transform Message (default
- HTTP Request/Listener (when streaming
Example behavior for small payloads)
response)
Components - Set Payload / Set Variable (if
- DataWeave (when using inputStream
reading entire payload)
instead of full data)
Reusability of Stream can be consumed only once unless it’s Data can be accessed multiple times
Data re-readable (like file streams). easily since it’s fully in memory.
When handling large payloads or files, e.g.,
When dealing with small payloads
Use Case reading a CSV → transforming → writing to
(JSON, XML, or small DB responses).
another system.
Example in read(payload, "application/csv", Normal DataWeave transformation
DataWeave {streaming: true}) without streaming.
💡 Example Scenario
🟢 Streaming Transformation
You read a 2GB CSV file and transform it to JSON.
<flow name="streamingExample">
<file:read path="C:/input/[Link]" outputMimeType="application/csv"/>
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[
%dw 2.0
output application/json
---
read(payload, "application/csv", { streaming: true })
]]></ee:set-payload>
</ee:message>
</ee:transform>
<file:write path="C:/output/[Link]"/>
</flow>
✅ Processes file chunk by chunk
✅ Prevents memory overload
🔴 Non-Streaming Transformation
<flow name="nonStreamingExample">
<file:read path="C:/input/[Link]" outputMimeType="application/csv"/>
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[
%dw 2.0
output application/json
---
read(payload, "application/csv")
]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
⚠️Loads the entire file into memory before transformation — fine for small files, risky for large ones.
🧠 Key Interview Tip
If asked “When should you use streaming?”, say:
Use streaming whenever dealing with large payloads, files, or data sources to optimize memory usage and
avoid performance bottlenecks.
If asked “Is DataWeave streaming by default?”, say:
By default, DataWeave transformations are non-streaming, but you can enable streaming explicitly using
the read() function with { streaming: true }
Memory Allocation and Garbage Collection for DataWeave?
🧩 How Mule Handles Memory Allocation and Garbage Collection for DataWeave
DataWeave runs inside the Mule Runtime Engine (Mule 4), which is built on the Java Virtual Machine
(JVM).
So, memory allocation and garbage collection are governed by JVM principles, but Mule adds its own
management layer to optimize DataWeave’s performance and avoid memory leaks.
⚙️1. DataWeave Memory Allocation Model
When Mule executes a DataWeave transformation, it manages data through streaming or in-memory
structures depending on the input and output types.
Type of Data Memory Handling Notes
Small Payloads (JSON, Fully loaded in JVM heap The payload is deserialized into DataWeave’s internal data
XML, small text) memory structure (CursorProvider, maps, arrays, etc.)
Large Payloads (files, Streamed using cursor providers
Only chunks are read at a time; prevents heap overflow.
streams, DB results) and temporary disk buffers
Type of Data Memory Handling Notes
Repeated access Stored in Mule’s internal cache
Increases CPU use but avoids re-reading sources.
payloads if needed
DataWeave’s internal engine uses lazy evaluation — meaning data is not read or transformed until required.
This minimizes unnecessary memory usage.
🧠 2. Cursor Providers and Streaming Buffers
Mule 4 uses a Cursor Stream Provider abstraction (e.g., RepeatableFileStoreCursorStreamProvider)
to manage streaming payloads.
When streaming is enabled, Mule does not load the entire content into memory.
It stores temporary chunks either:
o In JVM heap memory (for small data), or
o In temporary disk storage (for large streams).
This is configurable via:
mule:
streaming:
maxInMemorySize: 512KB
bufferSize: 1024KB
➡️When the in-memory buffer limit is reached, Mule automatically spills data to disk to protect the JVM
heap.
♻️3. Garbage Collection (GC) in Mule 4
Mule leverages Java’s Garbage Collector (GC) — usually G1GC (Garbage First Collector) — for heap
cleanup.
DataWeave scripts, variables, and payload references are normal Java objects.
When the flow or DataWeave transformation completes, Mule dereferences these objects.
The GC automatically reclaims memory once there are no active references.
However, Mule improves on top of JVM GC by:
Using stream cursors that automatically close streams after consumption.
Using reference management to detach large payloads once they are no longer needed.
Avoiding “dangling references” to old payloads by replacing the #[payload] at each component.
🚀 4. When DataWeave Causes Memory Pressure
DataWeave transformations may consume significant memory if:
1. You read the entire payload (e.g., read(payload, "application/csv") without streaming).
2. You store large objects in variables or session vars.
3. You use DataWeave operations like groupBy, distinctBy, or join on large datasets (these are in-
memory).
➡️Best practice: For large data, enable streaming or process in paged batches.
🧰 5. Tuning Memory and GC for DataWeave
You can control Mule’s memory behavior using JVM arguments and Mule runtime configs.
Example JVM settings:
-MX4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200
-Xmx4G → Sets maximum heap memory to 4 GB.
UseG1GC → Optimized GC for low-latency applications.
MaxGCPauseMillis → Targets shorter GC pauses.
Example streaming settings (in [Link] or global config):
mule:
streaming:
bufferSize: 1024KB
maxInMemorySize: 256KB
🧩 6. Memory Cleanup Process (Simplified Flow)
1. Flow executes DataWeave.
2. Mule loads payload as cursor/stream or in-memory object.
3. After transformation → output replaces payload.
4. Old payload reference cleared.
5. JVM GC reclaims memory automatically.
6. Any temp streaming buffers (files) are deleted once stream closes.
🧠 Interview Answer Summary
MuleSoft uses JVM-based garbage collection and memory allocation.
DataWeave transformations either load data into memory or process it as streams.
Mule 4 introduces cursor-based streaming, which minimizes heap usage by spilling large payloads to disk.
Once a transformation finishes, Mule releases object references, and JVM garbage collector reclaims
memory automatically.
For large payloads, enabling streaming and tuning maxInMemorySize and JVM heap are key to avoiding
OutOfMemory errors.
Best Practices to Avoid OutOfMemory Errors During DataWeave Transformations?
🧠 Best Practices to Avoid OutOfMemory Errors During DataWeave
Transformations
When Mule executes a DataWeave transformation, large payloads, collections, or heavy aggregations can
easily consume JVM heap memory if not handled properly.
To avoid OutOfMemoryError, you must focus on streaming, lazy evaluation, and resource cleanup.
⚙️1. Use Streaming Instead of In-Memory Processing
By default, DataWeave loads data into memory.
If you’re handling large files (CSV, JSON, XML, etc.), enable streaming so that data is read and processed
in chunks.
✅ Best Practice:
%dw 2.0
output application/json
---
read(payload, "application/csv", { streaming: true })
Or configure streaming globally:
mule:
streaming:
maxInMemorySize: 512KB
bufferSize: 1MB
👉 Why: Prevents Mule from loading the entire payload into heap memory.
📦 2. Use Cursor Streams (Repeatable Streams)
Whenever possible, use cursor-based streaming for connectors (like File, HTTP, or Database).
✅ Example:
<http:listener ... outputMimeType="application/json" streamPayload="true"/>
or
<file:read path="[Link]" outputMimeType="application/csv" />
➡️Mule uses CursorStreamProvider internally to handle large payloads safely — it keeps small data in
memory and large data on disk.
🧩 3. Avoid Storing Large Payloads in Variables or Session Vars
Never store a full payload or large collection inside variables, especially flowVars or sessionVars.
This keeps data alive in memory longer, blocking garbage collection.
❌ Bad:
<set-variable variableName="bigData" value="#[payload]" />
✅ Good:
Only store references or small metadata.
<set-variable variableName="fileName" value="#[[Link]]" />
⚙️4. Optimize DataWeave Transformations
Certain DataWeave functions are memory-heavy — like groupBy, distinctBy, reduce, join, etc.
Avoid applying them to huge datasets in one go.
✅ Best Practices:
Use filter, map, or flatMap in a streaming-friendly way.
Avoid nested maps on large collections.
Paginate large data sets (process in batches).
Example (using paging):
%dw 2.0
var batchSize = 1000
var batches = (0 to ((sizeOf(payload) / batchSize) as Number) - 1)
---
batches map (i) -> payload[(i * batchSize) to ((i + 1) * batchSize - 1)] map (item) ->
item
💾 5. Use File Store Cursor for Large Payloads
Configure Mule to use file-based streaming when data exceeds memory limits.
This ensures that only a small portion of the data is kept in heap memory.
✅ Example Configuration ([Link]):
mule:
streaming:
maxInMemorySize: 256KB
bufferSize: 512KB
👉 What happens:
If data > 256KB → Mule writes chunks to temporary disk files instead of the heap.
♻️6. Manage Memory via JVM and GC Tuning
Set appropriate JVM parameters for Mule runtime:
✅ Example (in [Link] or startup command):
-MX4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200
👉 Explanation:
-Xmx4G → Max 4GB heap
UseG1GC → Garbage-first collector, optimal for large heap
MaxGCPauseMillis → Keeps GC pauses short
🚀 7. Release Memory Early
Avoid holding onto payloads once they’re no longer needed.
For example, when you log or write to a file, set the payload to null or small data afterward:
✅ Example:
<file:write path="[Link]" />
<set-payload value="#[null]" />
This clears memory references and allows GC to reclaim space.
📊 8. Use ObjectStore for Large Temporary Data
If you need to store intermediate large datasets temporarily, use ObjectStore instead of variables.
It keeps data outside the JVM heap.
✅ Example:
<objectstore:store value="#[payload]" key="batch1" />
🔍 9. Monitor and Profile Memory Usage
Use Anypoint Monitoring or external tools (like JVisualVM, or JConsole) to track heap utilization.
Look for:
High “Old Gen” memory usage.
Frequent GC cycles.
Increasing memory over time (potential memory leaks).
🧠 10. Follow DataWeave Performance Best Practices
Don’t Do
Don’t use ++ to append lists repeatedly Use flatten or reduce
Don’t convert formats multiple times Use direct format conversion once
Don’t overuse dw::core::Arrays heavy ops Use simpler stream operations
Don’t log large payloads Log metadata only
🧩 Interview-Ready Summary Answer
To avoid OutOfMemory errors during DataWeave transformations, use streaming and cursor-based
processing for large payloads.
Avoid storing entire payloads in variables, enable file-based streaming, and optimize transformations to
process data in smaller chunks.
Tune JVM heap and GC settings appropriately, and clear unused references to allow faster garbage
collection.
Use ObjectStore for large temporary data and always monitor memory usage during performance testing.
What Is skipNullOn in DataWeave?
🧠 What Is skipNullOn in DataWeave?
skipNullOn is a DataWeave output directive that controls whether null values (or null keys) are included
or excluded in the final output.
It’s typically used in the output header of a DataWeave script, e.g.:
%dw 2.0
output application/json skipNullOn="everywhere"
---
payload
⚙️skipNullOn Options
Value Behavior
"attributes" Removes attributes with null values (for XML).
"elements" Removes elements with null values.
"keys" Removes keys (JSON objects) whose value is null.
"everywhere" Removes all null values, regardless of where they appear.
🚀 How skipNullOn Improves Performance in Large Transformations
When transforming large payloads (for example, hundreds of thousands of records or nested JSON
structures), null values can add significant processing overhead in both memory and serialization time.
skipNullOn optimizes transformation by reducing the amount of data held and serialized, as explained
below 👇
⚙️1. Reduces In-Memory Data Size
DataWeave builds in-memory structures (maps, arrays) before writing output.
Each null key/value pair still takes up space in memory and must be traversed.
✅ When you use:
output application/json skipNullOn="everywhere"
➡️DataWeave skips creating null fields altogether.
This directly reduces the size of the in-memory representation — less heap usage → lower GC pressure →
faster transformations.
⚡ 2. Reduces Serialization Workload
During output generation (especially JSON/XML), DataWeave has to serialize every element, including
nulls.
Example:
Without skipNullOn:
{
"id": 1,
"name": null,
"country": "IN"
}
With skipNullOn:
{
"id": 1,
"country": "IN"
}
➡️Mule doesn’t need to:
Write "name": null to the output stream.
Allocate memory for null serialization.
✅ Less data = fewer bytes written = faster I/O.
🧩 3. Improves Garbage Collection Efficiency
Each unused null field adds small but cumulative object references.
When processing millions of records, these can significantly delay GC and cause heap fragmentation.
✅ By skipping nulls:
Fewer temporary Java objects are created.
The JVM has less cleanup work.
GC cycles are shorter and less frequent.
🧠 4. Helps Downstream Systems and Connectors
Large payloads sent to APIs, queues, or files often get compressed or validated downstream.
By skipping nulls, you:
Reduce payload size.
Speed up transmission and parsing.
Save network bandwidth and CPU.
📊 Performance Example (Conceptual)
Let’s assume a transformation of 500,000 JSON objects, where 40% of fields are null.
Scenario Payload Size Time Taken Heap Usage
Without skipNullOn ~120 MB 15 seconds 1.2 GB
With skipNullOn="everywhere" ~72 MB 9 seconds 700 MB
(Numbers vary by data shape, but this is representative.)
🧩 5. Use Case Example
🔴 Without Optimization
%dw 2.0
output application/json
---
{
id: [Link],
name: [Link],
age: [Link],
email: [Link]
}
Produces:
{ "id": 1, "name": null, "age": 32, "email": null }
🟢 With skipNullOn
%dw 2.0
output application/json skipNullOn="everywhere"
---
{
id: [Link],
name: [Link],
age: [Link],
email: [Link]
}
Produces:
{ "id": 1, "age": 32 }
✅ Less output, less memory, faster serialization.
🧠 Interview-Ready Summary Answer
The skipNullOn directive improves performance in large DataWeave transformations by reducing
memory footprint, serialization time, and garbage collection pressure.
It prevents Mule from generating, storing, and serializing null values, which significantly improves
transformation speed and memory efficiency — especially with large JSON or XML payloads.
⚙️Bonus Tip
You can combine skipNullOn with streaming to handle massive datasets efficiently:
%dw 2.0
output application/json skipNullOn="everywhere"
---
read(payload, "application/csv", { streaming: true }) map (item) -> {
id: [Link],
name: if ([Link] != "") [Link] else null
}
This gives you:
Low memory usage (streaming)
Minimal payload size (skipNullOn)
💪 Perfect combo for high-performance transformations.
What Is Recursion in DataWeave?
🧠 What Is Recursion in DataWeave?
Recursion means a function calling itself until a termination (base) condition is met.
Since DataWeave is a functional language, it supports recursion natively (like JavaScript, Scala, etc.).
Recursion replaces loops (for, while) in functional programming.
⚙️How Recursion Works in DataWeave
1. You define a function using fun.
2. Inside that function, it calls itself.
3. You include a base condition to stop recursion (to avoid infinite loops).
4. Each recursive call builds up a call stack and resolves back once the base condition is met.
🧩 Example 1 – Sum of Numbers (Basic Recursion)
Let’s find the sum of numbers in a list using recursion.
%dw 2.0
output application/json
fun sumList(nums) =
if (isEmpty(nums))
0 // base case
else
nums[0] + sumList(nums[1 to -1]) // recursive call
---
sumList([1, 2, 3, 4, 5])
🔍 How It Works
Step Input Output
1 [1,2,3,4,5] 1 + sumList([2,3,4,5])
2 [2,3,4,5] 2 + sumList([3,4,5])
... ... ...
5 [] Base case → 0
🟢 Final Output: 15
🧩 Example 2 – Recursive Flattening of Nested Arrays
A real-world example: flattening a deeply nested JSON array recursively.
%dw 2.0
output application/json
fun flattenArray(arr) =
if (isEmpty(arr))
[]
else if (arr[0] is Array)
flattenArray(arr[0]) ++ flattenArray(arr[1 to -1])
else
[arr[0]] ++ flattenArray(arr[1 to -1])
---
flattenArray([1, [2, [3, 4]], 5])
🧾 Output
[1, 2, 3, 4, 5]
✅ Explanation:
If the first element is an array → recursively flatten it.
Otherwise, append it to the flattened rest of the array.
🧩 Example 3 – Recursive JSON Traversal
Here’s how recursion can traverse nested JSON objects to collect all keys:
%dw 2.0
output application/json
fun getAllKeys(obj) =
if (obj is Object)
(keysOf(obj) ++ (obj pluck (v, k) -> getAllKeys(v))) flatten
else
[]
---
getAllKeys({
id: 1,
name: "John",
address: {
city: "Pune",
pin: 411001,
location: { lat: 12.34, lon: 56.78 }
}
})
🧾 Output
["id", "name", "address", "city", "pin", "location", "lat", "lon"]
⚡ Important Notes About Recursion in DataWeave
Concept Description
Base Case Always define one to prevent infinite recursion.
Tail Recursion DataWeave doesn’t guarantee TCO (Tail Call Optimization) — so deep recursion can cause
Optimization a stack overflow.
When to Use Ideal for hierarchical or tree-like data (nested JSON, XML).
Alternative For large datasets, prefer reduce, map, or flatMap to avoid deep recursion depth.
🧠 Interview Summary Answer
In DataWeave, recursion is when a function calls itself to solve smaller parts of a problem until a base
condition is met.
It’s often used to traverse nested structures, calculate totals, or flatten hierarchical data.
Each recursive call processes one layer and returns results upward until the base case stops recursion.
What Is Currying in DataWeave?
🧠 What Is Currying in DataWeave?
Currying is a functional programming concept where a function with multiple parameters is
transformed into a sequence of functions,
each taking one parameter at a time.
In simpler words:
Currying lets you call a function partially — providing some arguments now, and the rest later.
DataWeave functions support currying because DataWeave is a functional language.
⚙️Normal Function vs Curried Function
🔹 Normal Function
fun add(x, y) = x + y
---
add(5, 3)
✅ Output → 8
Here, add expects both arguments together.
🔹 Curried Function
fun add(x) = (y) -> x + y
---
add(5)(3)
✅ Output → 8
Here:
add(5) returns a new function that expects the second argument y.
Then calling (3) applies that second argument.
🧩 Why Currying Is Useful
Currying enables:
1. Partial function application — reuse the same logic with some parameters fixed.
2. Cleaner and composable transformations — build complex functions from smaller ones.
🧩 Example 1 – Partial Application
%dw 2.0
output application/json
fun multiply(x) = (y) -> x * y
var double = multiply(2)
var triple = multiply(3)
---
{
double_5: double(5),
triple_5: triple(5)
}
✅ Output:
{
"double_5": 10,
"triple_5": 15
}
🔍 Explanation:
multiply(2) returns a new function that multiplies by 2 → double
multiply(3) returns a new function that multiplies by 3 → triple
You reuse the base logic efficiently.
🧩 Example 2 – Reusable Filters with Currying
Let’s create a curried filter function for reusable conditions:
%dw 2.0
output application/json
fun isGreaterThan(n) = (x) -> x > n
var greaterThan10 = isGreaterThan(10)
---
[5, 12, 20, 7, 15] filter greaterThan10
✅ Output:
[12, 20, 15]
🔍 Explanation:
isGreaterThan(10) returns a function that checks x > 10.
filter uses that returned function to filter the array.
🧩 Example 3 – Currying with Multiple Arguments
You can chain multiple parameters:
%dw 2.0
output application/json
fun addThree(x) = (y) -> (z) -> x + y + z
---
addThree(2)(3)(4)
✅ Output:
🔍 Step-by-step:
addThree(2) returns (y) -> (z) -> 2 + y + z
addThree(2)(3) returns (z) -> 2 + 3 + z
addThree(2)(3)(4) finally returns 9
⚙️Where It’s Useful in Mule / DataWeave
When writing modular, reusable transformations.
When you need to apply pre-configured logic repeatedly (e.g., validation, mapping rules).
When building dynamic filter or transformation functions.
🧠 Interview Summary Answer
Currying in DataWeave is the process of transforming a function that takes multiple arguments into a chain
of single-argument functions.
It allows partial application, meaning you can call a function with fewer arguments and get back a new
function waiting for the rest.
This improves reusability, composability, and cleaner functional design.
✅ Quick Recap Example
%dw 2.0
output application/json
fun add(x) = (y) -> x + y
---
add(10)(20)
🟢 Output → 30
💡 First call fixes x=10; second call applies y=20.
What Is a Custom DataWeave Module?
🧩 What Is a Custom DataWeave Module?
A custom DataWeave module is a .dwl file that contains reusable:
Functions
Constants
Variables
You can import that module into multiple flows or scripts — promoting reusability, maintainability, and
cleaner transformations.
🧱 1. Folder Structure
In a Mule 4 project, DataWeave modules are typically placed under:
src/main/resources/modules/
You can create subfolders for organization:
src/main/resources/modules/[Link]
src/main/resources/modules/[Link]
src/main/resources/modules/[Link]
⚙️2. Create a Custom Module
📄 File: [Link]
%dw 2.0
namespace commonUtils
// Example: Function to capitalize first letter of string
fun capitalize(str: String) =
upper(str[0]) ++ lower(str[1 to -1])
// Example: Function to safely get value or default
fun safeGet(value, default) =
if (value == null) default else value
// Example: Constant
var DEFAULT_COUNTRY = "IN"
✅ Key Points:
Start with %dw 2.0
Use a namespace (to identify your module)
Define functions and variables
Save the file with .dwl extension
🧩 3. Import and Use the Module in a Flow
📄 File: [Link]
%dw 2.0
import * from modules::commonUtils
output application/json
---
{
name: capitalize("muleSoft"),
country: safeGet(null, DEFAULT_COUNTRY)
}
✅ Output
{
"name": "Mulesoft",
"country": "IN"
}
🧠 4. Understanding Import Syntax
You can import modules in multiple ways:
Syntax Description
Imports everything (all functions and
import * from modules::commonUtils
variables).
import capitalize, safeGet from
modules::commonUtils Imports specific functions only.
import * from modules::commonUtils as common Imports everything under an alias.
✅ Example using alias:
%dw 2.0
import * from modules::commonUtils as util
output application/json
---
{
name: [Link]("john"),
country: util.DEFAULT_COUNTRY
}
🧩 5. Reusing Across Multiple Flows
Once your module is created under src/main/resources/modules,
you can reuse it across:
Multiple flows
Subflows
Global DataWeave scripts
No redeclaration needed — just import.
🧠 6. Benefits of Using Custom DataWeave Modules
Benefit Description
🧩 Reusability Common logic shared across flows.
🧹 Maintainability One place to update business rules.
⚡ Performance Faster deployment — avoids repetitive code.
🧱 Modularity Clean separation of transformation layers.
🔒 Consistency Reduces copy-paste transformation errors.
🧩 7. Example: Company-Wide Reusable Module
📄 modules/[Link]
%dw 2.0
namespace dateUtils
import * from dw::core::Dates
fun getCurrentDateTime() = now()
fun formatDate(dateStr, pattern) = (date(dateStr) as String {format: pattern})
fun addDaysToDate(dateStr, days) = date(dateStr) + |P$(days)D|
📄 [Link]
%dw 2.0
import * from modules::dateUtils
output application/json
---
{
today: formatDate(getCurrentDateTime(), "yyyy-MM-dd"),
nextReviewDate: addDaysToDate("2025-10-01", 30)
}
✅ Output:
{
"today": "2025-11-03",
"nextReviewDate": "2025-10-31"
}
⚠️8. Important Notes
Tip Description
🧩 File must be inside
Mule loads only from the resources folder.
src/main/resources/modules
📦 Use namespace and import via modules:: path Ensures no naming conflicts.
Mule runtime automatically loads your module — no extra
🚀 Recompile automatically
config needed.
Avoid using global state — functions should depend only on
🧠 Keep functions pure
inputs.
🧠 Interview-Ready Summary Answer
In Mule 4, you can create reusable DataWeave modules by defining common functions and constants in
.dwl files under src/main/resources/modules.
Each module should have a namespace, and can be imported into any DataWeave script using import
syntax.
This promotes code reusability, cleaner transformations, and easier maintenance across large
integration projects.
In DataWeave, the try and otherwise keywords are used for error handling
🧩 Purpose
In DataWeave, the try and otherwise keywords are used for error handling — similar to try-catch in
Java or C#.
They help you handle transformation errors gracefully without breaking the flow.
Instead of the whole transformation failing, you can define fallback behavior or default values.
⚙️Basic Syntax
try ( expression ) otherwise fallbackExpression
try (...) → Runs the main expression.
otherwise → Executes only if the try expression throws an error (e.g., null reference, type cast
failure, division by zero, etc.).
✅ Example 1: Handling Division Error
%dw 2.0
output application/json
---
{
result: try (10 / 0) otherwise "Error: Division by zero"
}
Output:
{
"result": "Error: Division by zero"
}
💡 Here, instead of throwing an exception, DataWeave catches it and returns the fallback message.
✅ Example 2: Handling Null Values
%dw 2.0
output application/json
var payload = { name: null }
---
{
userName: try (upper([Link])) otherwise "UNKNOWN"
}
Output:
{
"userName": "UNKNOWN"
}
💡 The upper() function would fail on null, but try...otherwise prevents the failure.
✅ Example 3: Fallback Default Value
%dw 2.0
output application/json
var data = {}
---
{
country: try ([Link]) otherwise "IN"
}
Output:
{
"country": "IN"
}
💡 Used to assign default values when a key or value is missing.
✅ Example 4: Try with Type Conversion
%dw 2.0
output application/json
---
{
age: try (toNumber("abc")) otherwise 0
}
Output:
{
"age": 0
}
💡 toNumber("abc") throws an error, but the fallback gives a safe value.
🧠 Example 5: Try-Otherwise with Complex Logic
You can use it inside functions or loops too:
%dw 2.0
output application/json
var numbers = [1, 2, "A", 3]
---
numbers map (item) -> try (item * 2) otherwise 0
Output:
[2, 4, 0, 6]
💡 Useful for partial transformation success — skips invalid entries but still processes valid data.
⚙️Example 6: Nesting Try-Otherwise
%dw 2.0
output application/json
---
{
result: try (
try (1 / 0) otherwise "Inner Fallback"
) otherwise "Outer Fallback"
}
Output:
{
"result": "Inner Fallback"
}
💡 You can nest multiple try...otherwise blocks for layered fallback logic.
🧱 How It Works Internally
try executes the expression.
If the expression throws a runtime error, it does not stop the DataWeave script.
Instead, it **returns the result of the otherwise block`.
If no error occurs, otherwise is ignored.
It’s a lightweight, expression-level error handling mechanism (not a global exception handler).
🚀 Best Practices
Best Practice Description
✅ Use for small, predictable failures Like null values, type conversions, or missing fields.
🚫 Don’t use for control flow Avoid using try...otherwise for regular branching logic.
Best Practice Description
⚙️Keep fallback meaningful Return a valid default or empty structure, not just an empty string.
🧩 Combine with default and if For better readability and safety.
🔥 Interview-Ready Summary Answer
In DataWeave, try and otherwise are used for handling runtime errors within transformations.
The try block evaluates an expression, and if it fails, the otherwise block provides a fallback value.
It helps prevent transformation failures (e.g., nulls, invalid conversions) and ensures robust, fault-tolerant
DataWeave scripts.
Example:
%dw 2.0
output application/json
---
{
result: try ([Link] / [Link]) otherwise 0
}
This ensures the transformation never breaks due to division by zero or missing data.
DataWeave script references a field that doesn’t exist in the input payload.
🧩 Scenario
Suppose your DataWeave script references a field that doesn’t exist in the input payload.
Example:
%dw 2.0
output application/json
---
{
value: [Link]
}
And your input is:
{
"name": "John"
}
⚙️What Happens?
👉 When you try to access a non-existent field in an object, DataWeave returns null — it does NOT
throw an error.
✅ Output:
{
"value": null
}
💡 So [Link] → null if "field" doesn’t exist in the input.
🧠 Explanation
DataWeave treats missing keys in objects as null values by default.
This design makes transformations tolerant of incomplete data structures.
However, if you try to perform an operation on that null, it can cause a runtime error.
⚠️Example — When It Fails
%dw 2.0
output application/json
---
{
upperValue: upper([Link])
}
Input:
{
"name": "John"
}
❌ This will throw an error:
"Cannot coerce a Null to a String"
Because [Link] = null, and upper() expects a string.
✅ Safe Access Practices
1️⃣ Use Default Value
Provide a fallback using the default operator:
[Link] default "N/A"
✅ If field doesn’t exist → "N/A"
2️⃣ Use Try–Otherwise
Safely handle runtime errors:
try (upper([Link])) otherwise "UNKNOWN"
✅ Prevents transformation failure even if field is missing or null.
3️⃣ Use Conditional Checks
Check before accessing deeply nested fields:
if ([Link]? and [Link] != null)
[Link]
else
"Not Available"
💡 The ? operator checks if a field exists in an object.
🧱 Special Case: Deeply Nested Fields
Example:
[Link]
If user exists but address doesn’t, it still returns null.
But if you try to access a property of a null object, it throws an error.
[Link]
If address is null → ❌ runtime error:
“Cannot access ‘city’ on Null value.”
✅ Safe way:
[Link]?.city default "Unknown"
The ?. (safe navigation operator) avoids the crash.
🚀 Best Practices Summary
Situation Behavior Safe Solution
[Link] doesn’t exist Returns null Use default or try...otherwise
Perform operation on null Throws runtime error Use try...otherwise
Access deep missing field Throws runtime error Use ?. safe navigation
🔥 Interview-Ready Short Answer
When you use [Link] and the field doesn’t exist, DataWeave returns null — it does not throw an
error.
However, if you try to perform an operation on that null, such as calling a function (upper(), arithmetic,
etc.), it will throw a runtime error.
To prevent this, use default, try...otherwise, or safe navigation (?.) operators.
How to log transformation errors (e.g., parsing failures, null pointer issues, or business
validation errors) inside a DataWeave script?
🧩 Goal
You want to log transformation errors (e.g., parsing failures, null pointer issues, or business validation
errors) inside a DataWeave script, without stopping the flow execution.
⚙️Important Concept
DataWeave itself doesn’t have a dedicated logger() function like Java or Mule’s Logger component.
However, you can trigger a log message by using Mule loggers, dw::Runtime::log(), or custom logging
patterns with try...otherwise.
✅ Option 1: Using dw::Runtime::log() (Best Practice in DW 2.4+)
Since Mule 4.4+ (and Anypoint Studio 7.10+), DataWeave provides a built-in module:
import * from dw::Runtime
This module gives access to runtime utilities, including logging.
Example:
%dw 2.0
import * from dw::Runtime
output application/json
---
{
result: try (
10 / 0
)
otherwise do {
log("Error during transformation: Division by zero", "ERROR"),
0
}
}
Output:
{
"result": 0
}
🪵 Mule Console Log:
ERROR: Error during transformation: Division by zero
💡 log(message, level) supports log levels: "TRACE", "DEBUG", "INFO", "WARN", "ERROR".
✅ Option 2: Log via try...otherwise and Mule Logger
If your Mule runtime version doesn’t support dw::Runtime::log(),
you can bubble the error up and log it in a Logger component after the Transform.
Example Flow:
<flow name="errorLoggingFlow">
<transform message="Transform with error">
<dw:transform-message>
<dw:set-payload><![CDATA[
%dw 2.0
output application/json
---
{
result: try (10 / 0) otherwise "Transformation Error"
}
]]></dw:set-payload>
</dw:transform-message>
</transform>
<logger level="ERROR" message="Payload: #[payload]" />
</flow>
💡 This approach is external — but preferred when you want consistent logging with Mule’s log4j
configuration.
✅ Option 3: Log with Custom Function
You can create a custom reusable logging function in a module.
📄 modules/[Link]
%dw 2.0
namespace loggerUtils
import * from dw::Runtime
fun logError(msg) = log(msg, "ERROR")
Then use it in any transformation:
%dw 2.0
import * from modules::loggerUtils
output application/json
---
{
result: try (
1 / 0
)
otherwise do {
logError("Division by zero occurred in transformation"),
0
}
}
✅ Option 4: Inline Logging with do Block
The do block allows you to execute side effects (like logging) within a transformation expression.
Example:
%dw 2.0
import * from dw::Runtime
output application/json
---
do {
log("Starting transformation", "INFO"),
result: try (1 / 0)
otherwise do {
log("Transformation failed: Division by zero", "ERROR"),
"Fallback"
}
}
🧠 This is clean, functional, and readable — ideal for production-grade transformations.
⚠️Note on Performance
Logging inside DataWeave adds slight runtime overhead — use only for error or debug-level
events.
Prefer centralized Mule loggers for business-level logging.
For very large payloads, avoid logging the full payload — log key fields or context only.
🧠 Interview-Ready Summary Answer
In DataWeave, transformation errors can be logged using try...otherwise along with the
dw::Runtime::log() function (available in Mule 4.4+).
This allows logging messages directly from inside the DataWeave script at different levels (INFO, WARN,
ERROR, etc.) without failing the flow.
Example:
%dw 2.0
import * from dw::Runtime
output application/json
---
{
result: try ([Link] / [Link])
otherwise do {
log("Transformation failed due to invalid data", "ERROR"),
0
}
}
This approach ensures graceful error handling and visibility during transformations.
Reuse the same DataWeave transformation logic?
🧩 Goal
You want to reuse the same DataWeave transformation logic (e.g., mapping or enrichment) across
multiple Mule flows or applications,
so you don’t repeat the same .dwl code everywhere.
✅ Main Reusability Options
# Approach Scope Use Case
1️ Create a reusable DataWeave module (.dwl) Project-level Share logic across multiple flows within the
# Approach Scope Use Case
⃣ same Mule app
2️ Use a global function library (custom module Organization- Reuse functions across multiple Mule
⃣ JAR) level applications
3️
Use a shared subflow or common flow Project-level Reuse full transformations (not just functions)
⃣
4️ Use a separate Mule domain project / shared Common transformations for multiple
Enterprise-level
⃣ library project APIs/projects
5️ Publish a MuleSoft Shared Library (Exchange
Org-wide Centralized governance and reuse across teams
⃣ Asset)
Let’s break down each with examples 👇
🧱 1️⃣ Reusable DataWeave Module (.dwl file)
📂 Folder structure:
src/main/resources/modules/[Link]
📄 [Link]
%dw 2.0
namespace commonTransform
fun mapCustomer(customer) =
{
fullName: upper([Link] ++ " " ++ [Link]),
country: [Link] default "IN"
}
Then import and reuse it anywhere:
📄 [Link]
%dw 2.0
import * from modules::commonTransform
output application/json
---
{
customer: mapCustomer([Link])
}
✅ Benefit:
Perfect for function-level reuse across multiple flows in the same project.
🧩 2️⃣ Reuse via Custom Function Library (Packaged Module JAR)
If you want to reuse transformations across multiple Mule apps,
you can package your .dwl modules as a JAR and publish it to Anypoint Exchange or Maven Nexus.
Steps:
1. Create a new Mule Plugin Project.
2. Add your .dwl module(s) under /src/main/resources/modules/.
3. Add a [Link] to package it as a JAR.
4. Publish it to Exchange.
5. Import in any Mule app using:
6. <dependency>
7. <groupId>[Link]</groupId>
8. <artifactId>common-dw-utils</artifactId>
9. <version>1.0.0</version>
10. </dependency>
11. Then just:
12. import * from modules::commonTransform
✅ Benefit:
Reusable across multiple APIs/projects in your organization — ideal for enterprise teams.
🧩 3️⃣ Reuse via Subflows or Common Flow References
If the transformation logic is part of a Mule flow (not just DataWeave function):
Example:
<sub-flow name="transformCustomerFlow">
<transform-message>
<dw:set-payload><![CDATA[
%dw 2.0
output application/json
---
{
name: upper([Link] ++ " " ++ [Link])
}
]]></dw:set-payload>
</transform-message>
</sub-flow>
Then call it from multiple places:
<flow name="orderFlow">
<flow-ref name="transformCustomerFlow"/>
</flow>
✅ Benefit:
Reuses entire transformation logic and ensures consistent mapping across flows.
🧩 4️⃣ Use a Shared Library or Domain Project
If multiple Mule applications need to share transformations:
Create a Common Mule Domain Project or Shared Library Project.
Place all .dwl modules in /src/main/resources/modules/.
Add the library as a dependency in your other Mule apps.
✅ Benefit:
Centralized version control and reusability across applications.
🧩 5️⃣ Publish as an Exchange Asset (Best Enterprise Practice)
1. Package the .dwl module or Mule configuration as a Reusable Exchange Asset.
2. Publish it to Anypoint Exchange.
3. Other developers can discover and import it directly via Exchange UI.
✅ Benefit:
Promotes organization-wide reuse.
Ensures consistent mapping and governance across multiple APIs.
🧠 Example Real-Time Scenario
You have a common customer transformation used across:
Order API
Invoice API
Shipment API
You can create one [Link]:
%dw 2.0
namespace customerTransform
fun mapCustomer(cust) = {
id: [Link],
name: upper([Link] ++ " " ++ [Link]),
contact: [Link] default "N/A"
}
Then simply import it in each flow’s DataWeave:
%dw 2.0
import * from modules::customerTransform
output application/json
---
mapCustomer([Link])
🧠 Interview-Ready Summary Answer
We can reuse the same transformation logic across multiple Mule flows by creating reusable DataWeave
modules (.dwl) under src/main/resources/modules and importing them using the import statement.
For larger reuse (across multiple Mule applications), we can package the module as a shared library or
publish it to Anypoint Exchange.
Alternatively, we can use common subflows or shared Mule domain projects for reusing transformation
logic across flows or projects.
✅ Example (concise version):
// modules/[Link]
%dw 2.0
namespace commonTransform
fun toUpperCaseName(n) = upper(n)
// usage
%dw 2.0
import * from modules::commonTransform
output application/json
---
{ name: toUpperCaseName([Link]) }
Would you like me to show a visual diagram of how reusable modules and subflows interact across
multiple Mule apps (Exchange + project structure)? It’s often a bonus point in architecture interviews.
Common reusable functions in dataweave?
🧩 Goal
You have two DataWeave files —
one contains common reusable functions, and the other is a main transformation file that wants to call
those functions.
✅ 1️⃣ Create the External Function File
Place your shared function file inside the Mule project’s resources directory:
📂 Project Structure
src/
└── main/
└── resources/
└── modules/
├── [Link]
└── [Link]
📄 [Link]
%dw 2.0
namespace stringUtils
fun capitalizeName(name: String) =
upper(name[0]) ++ lower(name[1 to -1])
fun concatNames(first: String, last: String) =
capitalizeName(first) ++ " " ++ capitalizeName(last)
✅ Notes:
%dw 2.0 → declares the DataWeave script version.
namespace stringUtils → gives this module an identity for imports.
.dwl extension is mandatory.
This file can contain multiple fun definitions (and var constants if needed).
✅ 2️⃣ Import and Call the External Function
Now in your main transformation, you can import and use those functions.
📄 [Link]
%dw 2.0
import * from modules::stringUtils
output application/json
---
{
fullName: concatNames("mULE", "SOFT")
}
✅ Output:
{
"fullName": "Mule Soft"
}
🧠 3️⃣ How Import Works in DataWeave
The syntax:
import * from modules::moduleName
or
import functionName from modules::moduleName
Syntax Description
import * from modules::stringUtils Imports all functions and variables from the file.
import concatNames from modules::stringUtils Imports only a specific function.
import * from modules::stringUtils as util Imports all functions under an alias (util).
Example using alias:
%dw 2.0
import * from modules::stringUtils as util
output application/json
---
{
fullName: [Link]("john", "doe")
}
✅ Output:
{
"fullName": "John Doe"
}
⚙️4️⃣ Folder Path Rules
When importing, you use the folder hierarchy as the module path:
File Location Import Path
src/main/resources/modules/[Link] modules::stringUtils
src/main/resources/common/[Link] common::stringUtils
src/main/resources/lib/utils/[Link] lib::utils::stringUtils
⚙️5️⃣ Passing Parameters Between Files
You can also call external functions with arguments, just like normal DataWeave functions:
%dw 2.0
import * from modules::mathUtils
output application/json
---
{
sum: addNumbers(10, 20)
}
📄 [Link]
%dw 2.0
namespace mathUtils
fun addNumbers(a: Number, b: Number) = a + b
✅ Output:
{
"sum": 30
}
🧱 6️⃣ Benefits of External Function Files
Benefit Description
🧩 Reusability Avoids duplicate logic across flows.
🧹 Maintainability Update one place — all transformations get updated.
⚙️Modularity Clean separation of logic.
🚀 Performance Compiled once and reused during runtime.
⚠️7️⃣ Common Mistakes to Avoid
Mistake Explanation
❌ Using file paths like ../modules/[Link] Not supported — must use module path syntax.
❌ Forgetting %dw 2.0 in the external file Mule won’t load it as a valid DataWeave script.
❌ Missing namespace May cause import naming conflicts.
❌ File outside src/main/resources/ Mule runtime won’t find the module.
🧠 Interview-Ready Answer
To call an external DataWeave function from another .dwl file, you first define reusable functions inside a
.dwl file under src/main/resources/modules/ with a namespace.
Then, you import that file in another DataWeave script using the import statement and call the function by
name (optionally using an alias).
Example:
%dw 2.0
import * from modules::stringUtils
output application/json
---
{ name: concatNames("john", "doe") }
This ensures clean, modular, and reusable transformation logic across multiple flows or applications.
You want your Mule app to use different configuration values (like URLs, DB credentials,
API keys, etc.) for each environment without changing the code.
🧩 Goal
You want your Mule app to use different configuration values (like URLs, DB credentials, API keys, etc.)
for each environment without changing the code.
✅ 1️⃣ The Standard Practice: Use Property Files
Mule supports environment-specific property files located under:
📂 Project structure
src/main/resources/
├── [Link]
├── [Link]
├── [Link]
├── [Link]
├── [Link]
└── [Link]
Each file stores environment-specific properties.
Example: [Link]
db:
host: localhost
port: 3306
user: root
password: root123
api:
baseUrl: "[Link]
Example: [Link]
db:
host: prod-db-server
port: 3306
user: admin
password: ${secure::db_password}
api:
baseUrl: "[Link]
✅ 2️⃣ Refer to Properties in Mule Configuration
You can reference them anywhere using ${[Link]} syntax.
📄 [Link]
<configuration-properties file="config-${[Link]}.yaml" doc:name="Configuration
properties"/>
<http:request-config name="HTTP_Request_Config" >
<http:request-connection host="${[Link]}" port="443" protocol="HTTPS" />
</http:request-config>
💡 ${[Link]} is the environment variable that Mule reads at runtime (explained below).
✅ 3️⃣ Activate the Correct Environment
When you run or deploy the app, Mule picks the right configuration file based on the value of the [Link]
variable.
▶️Locally (Anypoint Studio)
Go to:
Run Configurations → Arguments → VM arguments:
-[Link]=dev
▶️CloudHub / Runtime Manager
Set Environment Variables in Runtime Manager:
Name Value
[Link] qa
✅ Mule automatically loads [Link].
✅ 4️⃣ Secure Sensitive Data Using Secure Property Placeholder
Never store credentials (passwords, keys) in plain text!
Use the Secure Properties Tool:
[Link]
Example:
java -cp [Link] [Link] \
stringEncrypt \
AES \
mySecretPassword \
myEncryptionKey
It generates something like:
![kfj83hJd93jf92hfj==]
Then use this in your YAML:
db:
password: "![kfj83hJd93jf92hfj==]"
And declare the secure properties in your config:
<secure-property-placeholder
name="secure-properties"
file="config-${[Link]}.yaml"
key="myEncryptionKey"
algorithm="AES"/>
✅ 5️⃣ Environment-Specific Property Loading Logic
Example in Mule config:
<configuration-properties name="config" file="config-${[Link]}.yaml" />
For DEV → loads [Link]
For QA → loads [Link]
For PROD → loads [Link]
This avoids manual changes when promoting the app between environments.
✅ 6️⃣ Optional: Use Anypoint Runtime Manager (ARM) Secrets Manager
In CloudHub 2.0, you can manage secure configurations directly in Secrets Manager:
Store sensitive data like passwords, tokens.
Reference them via ${secure::keyName} syntax.
Mule automatically injects them during runtime.
✅ Example:
db:
password: ${secure::dbPassword}
🧠 7️⃣ Alternative: Centralized Config Using Anypoint Runtime Fabric
In Mule 4.4+, you can store configuration in externalized config maps when deploying to Runtime Fabric,
managed by DevOps or CI/CD pipelines.
⚙️8️⃣ Real-World Example
Let’s say you have a DB connector and an API request config.
📄 [Link]
<configuration-properties file="config-${[Link]}.yaml" />
<db:config name="DB_Config" >
<db:my-sql-connection host="${[Link]}" port="${[Link]}"
user="${[Link]}" password="${[Link]}" database="orders"/>
</db:config>
<http:request-config name="HTTP_Request_Config" >
<http:request-connection host="${[Link]}" port="443" protocol="HTTPS" />
</http:request-config>
📄 [Link]
db:
host: localhost
port: 3306
user: root
password: root123
api:
baseUrl: [Link]
📄 [Link]
db:
host: prod-db
port: 3306
user: admin
password: ${secure::db_password}
api:
baseUrl: [Link]
When deployed:
In DEV, it connects to local DB.
In PROD, it uses the production database and secure password.
🧠 Interview-Ready Summary Answer
In Mule 4, environment-specific configurations are handled using property placeholder files (e.g., config-
[Link], [Link], [Link]) and a runtime variable ${[Link]} that determines
which file to load.
The properties are referenced using ${propertyName} syntax inside Mule configs.
For sensitive values, we use the Secure Property Placeholder or Secrets Manager in CloudHub.
This approach ensures configuration separation, reusability, and security across all environments.
✅ Short Example for Interviews
<configuration-properties file="config-${[Link]}.yaml" />
<db:config name="DB_Config" >
<db:my-sql-connection
host="${[Link]}"
user="${[Link]}"
password="${[Link]}" />
</db:config>
Property files:
[Link]
[Link]
Set [Link]: -[Link]=prod
What is lazy vs eager in dataweave?
🧠 1. Eager Evaluation
Eager evaluation means the expression is evaluated immediately, and all results are computed at once —
even if you only need part of them.
Example:
%dw 2.0
output application/json
---
[1, 2, 3, 4, 5] map ((n) -> n * 2)
➡️Here, DataWeave will:
Compute all the results of map right away.
Produce [2, 4, 6, 8, 10] before moving on.
Eager collections are stored fully in memory, which is fine for small or moderate datasets.
💤 2. Lazy Evaluation
Lazy evaluation means the expression is evaluated only when needed — DataWeave doesn’t compute all
elements immediately.
Instead, it creates a stream-like structure that computes values on demand.
Example:
%dw 2.0
output application/json
---
(1 to 1000000) map ((n) -> n * 2) filter ((n) -> n < 10)
➡️In a lazy context, DataWeave won’t calculate n * 2 for all 1,000,000 items.
It will compute just enough to satisfy the filter — much more memory efficient.
⚙️How to Control Laziness
You can control whether DataWeave processes data lazily or eagerly:
Function Description
map Eager — creates a new collection immediately.
mapObject Eager for objects.
mapObjectL Lazy version (the “L” stands for lazy).
filter Lazy.
orderBy Eager (needs to see all elements).
pluck Lazy.
dw::core::Streams::toStream() Converts a collection to a lazy stream.
dw::core::Streams::fromStream() Converts a stream (lazy) back to a normal eager collection.
Example:
%dw 2.0
import * from dw::core::Streams
output application/json
var lazyData = toStream([1, 2, 3, 4, 5]) map ((x) -> x * 10)
---
fromStream(lazyData)
➡️The transformation is lazy until fromStream is called.
🚀 When to Use Which
Use Case Recommended Mode
Small datasets, simple transformations Eager (default)
Large files (CSV, JSON), streaming APIs, memory constraints Lazy (use streams)
✅ Summary
Concept Description
Eager Computes all results right away (more memory use, faster small data).
Lazy Computes values only when needed (less memory, better for large/streamed data).
Streams API Allows you to explicitly make DataWeave operations lazy.
Eager Vs Lazy Approach
Eager and Lazy are two different approaches to how a program
executes computations or processes data. Here’s an easy-to-
understand explanation:
1. Eager (Eager Evaluation)
Meaning: All computations are executed immediately, even if
the results are not used.
Analogy: Imagine you’re asked to prepare food for guests
who might come. Using the eager approach, you cook everything
right away, even if the guests haven’t arrived.
Advantages:
Results are ready immediately when needed later.
Simple and suitable for small or static programs.
Disadvantages:
Can waste resources if the results are not used.
Requires more memory or time upfront.
Example:
const a = 5;
const b = 10;
const result = a * b; // Computed immediately, even if not yet used
[Link](result); // Prints the result (50)
Get Khairul Muhtadin’s stories in your inbox
Join Medium for free to get updates from this writer.
Subscribe
2. Lazy (Lazy Evaluation)
Meaning: Computation is delayed until the result is actually
needed.
Analogy: If guests might come, you only start cooking when they
actually show up at the door.
Advantages:
Saves resources by only calculating what’s needed.
Great for handling large data or situations where not all results
are required.
Disadvantages:
Slightly more complex to implement.
If used improperly, it may slow things down as computations
happen at the last moment.
Example:
%dw 2.0
output application/json
var lazyMultiply = (a, b) -> () -> a * b
var lazyResult = lazyMultiply(5, 10)() // Calling the function
---
lazyResult
Key Differences
Press enter or click to view image in full size
Summary:
Use eager if the data is small or all results will be used.
Use lazy for efficiency, especially when dealing with large data or
when only a portion of the results is required.