Sunteți pe pagina 1din 38

DATAWEAVE STREAMING IN MULE 4

In this tutorial we will demonstrate how we can use dataweave streaming in mule 4 which is useful to
process the large files quickly without any memory issues which consume less resources compare to old
way of reading and writing big documents.
Supported Format
1. JSON
2. XML
3. CSV
Limitations
4. When we select the deferred=true and if there is any error occurred in transform component where you
set this property then error will not be thrown from that transform component
5. Streaming does not support random access
How to enable streaming
There are below configuration that we need to perform to enable streaming
1. Streaming property: To read source data as stream
1. Deferred property: To pass the output stream to message processor
1. We can enable streaming with setting outputMimeType with datasource which can be a listener, File
Listener, FTP listener
Now we will create a sample application where we are going to read the 1 Million records from CSV using
file operation and transform the data to application/json and write the same to folder.
We will perform the operation with streaming and without streaming and see how much time it has taken
to process the records and convert to json format and compare the result

Create a sample project and drag and drop File Listener and configure the streaming

<file:listener doc:name="On New or Updated File" doc:id="273e2ecc-


22a5-47db-bf1f-7656402944c2"
directory="C:\data" moveToDirectory="C:\dev\src" autoDelete="true"
outputMimeType="application/csv; streaming=true">
<scheduling-strategy >
<fixed-frequency frequency="15" timeUnit="SECONDS"/>
</scheduling-strategy>
</file:listener>
Perform the Transform to convert the data to JSON format and set deferred=true

%dw 2.0
output application/json deferred=true
---
Payload
Configure the write operation to write the json file
Deploy the project and write the sample file in Data folder , file will be processed automatically to
destination, we can see below 1 M records csv file is processed and converted to JSON in 11 Seconds
when the streaming is ON

Now we will deploy the project without streaming and deploy the application, we can see the processing
time to convert the file is 31 Seconds

Sample application: DataweaveStreaming Sample

DATAWEAVE 2.3.0 NEW FEATURES

In this tutorial we will demonstrate Dataweave 2.3.0 New Features, it is supported for mule runtime 4.3.0
or later.

Update Operator
A new update operator added as part of Dataweave 2.3.0 which is used to update the specific field with
new value, earlier we used to go through all the key value pair to update the values, with below example
we can see Address1,Address2 and PostalCode updated with new values
Sample Input:
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Flat 101",
"ADDRESS2": "Viman Nagar 1",
"POSTALCODE": "201018",
"CITY": "PUNE"
}
Set the variable as NewAddress with value “Updated Address”
Write the Dataweave expression to update the values for few fields
Dataweave Expression:
%dw 2.0
output application/json
---
payload update {
case ADDRESS1 at .ADDRESS1 -> vars.NewAddress
case ADDRESS2 at .ADDRESS2 -> vars.NewAddress
case POSTALCODE at .POSTALCODE -> "110034"
}
Result:
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Updated Adress",
"ADDRESS2": "Updated Adress",
"POSTALCODE": "110034",
"CITY": "PUNE"
}

Conditional Update
Using Update operator you can update the value for a specific field on the basis of some condition
we can see below the fields are updated
Sample Input:
[
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Flat 101",
"ADDRESS2": "Viman Nagar 1",
"POSTALCODE": "201018",
"CITY": "PUNE"
},
{
"CUSTOMER_ID": 2,
"CUSTOMER_NAME": "TEST12",
"ADDRESS1": "Flat 102",
"ADDRESS2": "Viman Nagar 2",
"POSTALCODE": "201018",
"CITY": "PUNE"
}
]
Dataweave Expression:
%dw 2.0
output application/json
---
payload map ((user) ->
user update {
case ADDRESS1 at .ADDRESS1 if(ADDRESS1 contains "101") -> ADDRESS1
++ " UK"
case ADDRESS2 at .ADDRESS2 if(ADDRESS2 contains "Viman") ->
ADDRESS2 ++ " UK"
}
)
Result:
[
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Flat 101 UK",
"ADDRESS2": "Viman Nagar 1 UK",
"POSTALCODE": "201018",
"CITY": "PUNE"
},
{
"CUSTOMER_ID": 2,
"CUSTOMER_NAME": "TEST12",
"ADDRESS1": "Flat 102",
"ADDRESS2": "Viman Nagar 2 UK",
"POSTALCODE": "201018",
"CITY": "PUNE"
}
]

namesOf
This function is used to return array of string for all the keys inside a object, it works on the object and
return array
Sample Input:
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Updated Adress",
"ADDRESS2": "Updated Adress",
"POSTALCODE": "110034",
"CITY": "PUNE"
}
Dataweave Expression:
%dw 2.0
output application/json
---
{
"allkeys" : namesOf(payload)
}
Result:
{
"allkeys": [
"CUSTOMER_ID",
"CUSTOMER_NAME",
"ADDRESS1",
"ADDRESS2",
"POSTALCODE",
"CITY"
]
}

valuesOf
This function is used to return array of string for all the values inside a object, it works on the object and
return array
Sample Input:
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Flat 101",
"ADDRESS2": "Viman Nagar 1",
"POSTALCODE": "201018",
"CITY": "PUNE"
}
Dataweave Expression:
%dw 2.0
output application/json
---
{
"allvalues" : valuesOf(payload)
}
Result:
{
"allvalues": [
1,
"TEST11",
"Flat 101",
"Viman Nagar 1",
"201018",
"PUNE"
]
}

withMaxSize
This function is used the get the string value on the basis of the length defined withMaxSize, if the defined
length is less that the string value then it cuts the length from left to right
With below example we can see we have extracted the string value for fields like
CUSTOMER_NAME,ADDRESS1,ADDRESS2
Sample Input:
[
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Flat 101",
"ADDRESS2": "Viman Nagar 1",
"POSTALCODE": "201018",
"CITY": "PUNE"
},
{
"CUSTOMER_ID": 2,
"CUSTOMER_NAME": "TEST12",
"ADDRESS1": "Flat 102",
"ADDRESS2": "Viman Nagar 2",
"POSTALCODE": "201018",
"CITY": "PUNE"
}
]
Dataweave Expression:
%dw 2.0
import withMaxSize from dw::core::Strings
output application/json
---
payload map () -&amp;gt;
{
"CUSTOMER_ID":$.CUSTOMER_ID ,
"CUSTOMER_NAME":$.CUSTOMER_NAME withMaxSize 4,
"ADDRESS1":$.ADDRESS1 withMaxSize 5,
"ADDRESS2":$.ADDRESS2 withMaxSize 5
}
Result:
[
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST",
"ADDRESS1": "Flat ",
"ADDRESS2": "Viman"
},
{
"CUSTOMER_ID": 2,
"CUSTOMER_NAME": "TEST",
"ADDRESS1": "Flat ",
"ADDRESS2": "Viman"
}
]

Upserting Using Update Operator


Update operator enables you to insert a field if it is not present by using the ! symbol at the end of the
selector expression.
In below example we can see Email field is missing and we have inserted the Email field using Update
operator using simple data weave expression
Sample Input:
[
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Flat 101",
"ADDRESS2": "Viman Nagar 1",
"POSTALCODE": "201018",
"CITY": "PUNE"
},
{
"CUSTOMER_ID": 2,
"CUSTOMER_NAME": "TEST12",
"ADDRESS1": "Flat 102",
"ADDRESS2": "Viman Nagar 2",
"POSTALCODE": "201018",
"CITY": "PUNE"
},
{
"CUSTOMER_ID": 2,
"CUSTOMER_NAME": "TEST12",
"ADDRESS1": "Flat 102",
"ADDRESS2": "Viman Nagar 2",
"POSTALCODE": "201018",
"CITY": "PUNE"
}
]
Dataweave Expression:
%dw 2.0
output application/json
---
payload map ((user) ->
user update {
case EMAIL at .EMAIL! -> if(EMAIL == null) "test@gmail.com" else
EMAIL
})
Result:
[
{
"CUSTOMER_ID": 1,
"CUSTOMER_NAME": "TEST11",
"ADDRESS1": "Flat 101",
"ADDRESS2": "Viman Nagar 1",
"POSTALCODE": "201018",
"CITY": "PUNE",
"EMAIL": "test@gmail.com"
},
{
"CUSTOMER_ID": 2,
"CUSTOMER_NAME": "TEST12",
"ADDRESS1": "Flat 102",
"ADDRESS2": "Viman Nagar 2",
"POSTALCODE": "201018",
"CITY": "PUNE",
"EMAIL": "test@gmail.com"
},
{
"CUSTOMER_ID": 2,
"CUSTOMER_NAME": "TEST12",
"ADDRESS1": "Flat 102",
"ADDRESS2": "Viman Nagar 2",
"POSTALCODE": "201018",
"CITY": "PUNE",
"EMAIL": "test@gmail.com"
}
]

MANIPULATION ON ARRAY IN MULE 4

In this tutorial we will demonstrate how can we do Manipulation On Array In Mule 4. To use this module,
we first need to import DataWeave code, for example, by adding the line import * from dw::core::Arrays
to the header of your DataWeave script
Please find below few important Array function which will be useful while working on Array In
Dataweave
Note: This Module can be used in Dataweave 2.2 and later

Drop Function

This function is introduced is Dataweave 2.2.0


This function drops the elements from array and return the remaining elements as per the condition.

%dw 2.0
import * from dw::core::Arrays
var samplearray = ["124", "35454", "Sachin","Amit"]
output application/json
---
drop(samplearray, 2)
Result:
[
"Sachin",
"Amit"
]

IndexOf Function

It Returns the index of the first occurrence of an element within the array. If the value is not found it will
return -1

Dataweave Expression:
%dw 2.0
import * from dw::core::Arrays
var samplearray = ["124", "35454", "Sachin","Amit"]
output application/json
---
indexOf(samplearray, "Sachin")
Result:
2

takeWhile Function

Selects elements from the array while the condition is met but stops the selection process when it reaches
an element that fails to satisfy the condition

Dataweave Expression:
%dw 2.0
import * from dw::core::Arrays
output application/json
var arr = [1,2,3,4,1,2]
---
arr takeWhile $ &lt;= 2
Result:
[
1,
2
]

sumBy Function

It returns the sum of the values inside array


Input:
[ { items: 233}, { items: 324 }, { items: 30 } ]

Dataweave Expression:
%dw 2.0
import * from dw::core::Arrays
output application/json
---
{
"TotalItems" : [
{ items: 233},
{ items: 324 },
{ items: 30 }
] sumBy $.items
}
Result:
{
"TotalItems": 587
}

Join 2 Arrays With Matching Id Using Join Function

In this part we will create a dataweave expression which will join 2 Different Array on ths basis of
the ID
Input:
Items Array
[{id: "12", name:"Tea"},{id: "22", name:"Salt"},{id: "3",
name:"Soap"},{id: "5", name:"Butter"}]
Price Array
[{Id: "12", price:123},{Id: "3", price:24}, {Id: "22", price:20},
{Id: "4", price:456}]

Dataweave Expression:
%dw 2.0
import * from dw::core::Arrays
var items = [{id: "12", name:"Tea"},{id: "22", name:"Salt"},{id:
"3", name:"Soap"},{id: "5", name:"Butter"}]
var Prices = [{Id: "12", price:123},{Id: "3", price:24}, {Id: "22",
price:20}, {Id: "4", price:456}]
output application/json
---
join(items, Prices, (item) -> item.id, (price) -> price.Id)

Result:
[
{
"l": {
"id": "12",
"name": "Tea"
},
"r": {
"Id": "12",
"price": 123
}
},
{
"l": {
"id": "22",
"name": "Salt"
},
"r": {
"Id": "22",
"price": 20
}
},
{
"l": {
"id": "3",
"name": "Soap"
},
"r": {
"Id": "3",
"price": 24
}
}
]

MANIPULATE DATE TIME OPERATIONS IN


DATAWEAVE

This tutorial talks about how to manipulate different Date time operations in Dataweave, it include various
Dataweave date time functions to perform date time conversions in different formats.
After this tutorial you will be able to perform different date time operations

Convert Current Datetime to CST Timezone

Dateweave Expression:
%dw 2.0
output application/java
---
now() as DateTime >> 'America/Chicago'
Result:
2020-07-19T09:56:14.020-05:00[America/Chicago]

Convert Current DateTime to specific string format(yyyy-MM-dd)

Dateweave Expression:
%dw 2.0
output application/java
---
now() as DateTime as String {format: "yyyy-MM-dd"}
Result:
2020-07-19

Convert Current DateTime to specific string format(yyyy-MMM-dd)

Dateweave Expression:
%dw 2.0
output application/java
---
now() as DateTime as String {format: "yyyy-MMM-dd"}
Result:
2020-Jul-19

Convert Current DateTime to specific string format( AM/PM)

Dateweave Expression:
%dw 2.0
output application/java
---
now() as DateTime as String {format : "d-MM-yyyy h:mm:ss a"}
Result:
19-07-2020 9:02:48 PM

Fetch Current Date In dataweave

Dateweave Expression:
%dw 2.0
output application/java
---
now() as Date
Result:
19-07-2020

Fetch Current Time In dataweave

Dateweave Expression:
%dw 2.0
output application/java
---
now() as Time
Result:
20:41:12.170+05:30

Format Time In dataweave(HH:MM:SS)

Dateweave Expression:
%dw 2.0
output application/java
---
now() as String {format: "hh:m:s"}
Result:
08:46:28

Fetch Year From Current Date in dataweave

Dateweave Expression:
%dw 2.0
output application/java
---
now().year
Result:
2020

Fetch current day value from current Date in dateweave

Dateweave Expression:
%dw 2.0
output application/java
---
now().day
Result:
19

Fetch month value from Current Date in dataweave

Dateweave Expression:
%dw 2.0
output application/java
---
now().month
Result:
7
Add,Substract Date and Time in dataweave
In this part we will see few examples where we will add and substract the day and time and use P as period
date type

Get 2 Day prior Date

Dataweave Expression:
%dw 2.0
output application/java
---
now() - |P2D|
Result:
2020-07-20T13:27:16.731+05:30[Asia/Calcutta]

Get 2 Day prior Date from Custom Date Format

Dataweave Expression:
%dw 2.0
output application/java
---
"2020-02-01" - |P2D|
Result:
2020-01-30

Add No of Days to Current Date


Dataweave Expression:
%dw 2.0
output application/java
---
now() + |P2D|
Result:
2020-07-24T13:34:23.548+05:30[Asia/Calcutta]

Add No of Days to Custom Date

Dataweave Expression:
%dw 2.0
output application/java
---
"2020-02-01" + |P2D|
Result:
2020-02-03

Add No of Years to Current Date

Dataweave Expression:
%dw 2.0
output application/java
---
now() + |P2Y|
Result:
2022-07-22T13:36:45.855+05:30[Asia/Calcutta]

Add No of Years to Custom Formatted Date

Dataweave Expression:
%dw 2.0
output application/java
---
"2020-02-01" + |P2Y|
Result:
2022-02-01

Substract No of Years From Current Date


Dataweave Expression:
%dw 2.0
output application/java
---
now() - |P10Y|
Result:
2010-07-22T13:39:52.551+05:30[Asia/Calcutta]

Add Hours,Minute,Time In Current Time: we are adding 2 Hours,13 Minute and 9 Seconds, you can
also substart the same using – symbol

Dataweave Expression:
%dw 2.0
output application/java
---
now() as String {format: "hh:m:s"} + |PT2H13M9S|
Result:
03:59:03Z

How to substract specific year with specific date and time from single dataweave expression

Dataweave Expression:
%dw 2.0
output application/java
---
|2020-11-02T23:57:59| - |P2Y9M1D| - |PT50M510S| + |PT3H|
Result:
2018-02-02T01:59:29

Compare 2 Dates In Dataweave

Dataweave Expression:
%dw 2.0
output application/java
---
now() as DateTime as String {format: "yyyy-MM-dd"} < "2020-09-10"
Result:
True
Dataweave Expression:
%dw 2.0
output application/java
---
now() as DateTime as String {format: "yyyy-MM-dd"} < "2020-09-10"
Result:
false

XML PROCESSING OR PARSING

XML processing or parsing in Dataweave become somewhat tricky as it depend on the input type of the
XML
Two type of XML input request we can get
Include NameSpace
<?xml version = "1.0" encoding="UTF-8" standalone="yes"?>
<org:employees xmlns:org="http://www.mycompany.org/employees">
<org:employee>
<org:name age="22">
<org:lastname>Kelly</org:lastname>
<org:firstname>Grace</org:firstname>
</org:name>
<org:hiredate>October 15, 2005</org:hiredate>
<org:projects>
<org:project>
<org:product>Printer</org:product>
</org:project>
</org:projects>
</org:employee>
<org:employee>
<org:name age="32">
<org:lastname>Grant</org:lastname>
<org:firstname>Cary</org:firstname>
</org:name>
<org:hiredate>October 20, 2005</org:hiredate>
<org:projects>
<org:project>
<org:product>Desktop</org:product>
</org:project>
</org:projects>
</org:employee>
<org:employee>
<org:name age="42">
<org:lastname>Gable</org:lastname>
<org:firstname>Clark</org:firstname>
</org:name>
<org:hiredate>October 25, 2005</org:hiredate>
<org:projects>
<org:project>
<org:product>Keyboard</org:product>
</org:project>
</org:projects>
</org:employee>
</org:employees>

No Namespace
<?xml version = "1.0" encoding="UTF-8" standalone="yes"?>
<employees>
<employee>
<name age="22">
<lastname>Kelly</lastname>
<firstname>Grace</firstname>
</name>
<hiredate>October 15, 2005</hiredate>
<projects>
<project>
<product>Printer</product>
</project>
</projects>
</employee>
<employee>
<name age="32">
<lastname>Grant</lastname>
<firstname>Cary</firstname>
</name>
<hiredate>October 20, 2005</hiredate>
<projects>
<project>
<product>Desktop</product>
</project>
</projects>
</employee>
<employee>
<name age="42">
<lastname>Gable</lastname>
<firstname>Clark</firstname>
</name>
<hiredate>October 25, 2005</hiredate>
<projects>
<project>
<product>Keyboard</product>
</project>
</projects>
</employee>
</employees>

Processing of both somewhat get differ in dataweave


Let’s start with Namespace first
For the namespace XML input below are the things we have to take care
1. Namespace should be defined to target the xml element like ns org
http://www.mycompany.org/employees
2. If we have to capture the reoccurring element then we have to put * like *org#employee
3. To get the attribute we have to use like $.org#name.@age
Dataweave
%dw 2.0
output application/json
ns org http://www.mycompany.org/employees
---
payload.org#employees.*org#employee map {
fullname : $.org#name.org#firstname ++ " " ++
$.org#name.org#lastname,
age: $.org#name.@age,
hiredate : $.org#hiredate,
product : $.org#projects.org#project.org#product
}
Output
[
{
"fullname": "Grace Kelly",
"age": "22",
"hiredate": "October 15, 2005",
"product": "Printer"
},
{
"fullname": "Cary Grant",
"age": "32",
"hiredate": "October 20, 2005",
"product": "Desktop"
},
{
"fullname": "Clark Gable",
"age": "42",
"hiredate": "October 25, 2005",
"product": "Keyboard"
}
]

With filter criteria


%dw 2.0
output application/json
ns org http://www.mycompany.org/employees
---
payload.org#employees.*org#employee filter($.org#name.@age > 30) map
{
fullname : $.org#name.org#firstname ++ " " ++
$.org#name.org#lastname,
age: $.org#name.@age,
hiredate : $.org#hiredate,
product : $.org#projects.org#project.org#product
}
Output
[
{
"fullname": "Cary Grant",
"age": "32",
"hiredate": "October 20, 2005",
"product": "Desktop"
},
{
"fullname": "Clark Gable",
"age": "42",
"hiredate": "October 25, 2005",
"product": "Keyboard"
}
]

Let process input XML having no namespace


We don’t have to include namespace while targeting the XML element
Dataweave
%dw 2.0
output application/json
---
payload.employees.*employee map {
fullname : $.name.firstname ++ " " ++ $.name.lastname,
age: $.name.@age,
hiredate : $.hiredate,
product : $.projects.project.product
}
Output
[
{
"fullname": "Grace Kelly",
"age": "22",
"hiredate": "October 15, 2005",
"product": "Printer"
},
{
"fullname": "Cary Grant",
"age": "32",
"hiredate": "October 20, 2005",
"product": "Desktop"
},
{
"fullname": "Clark Gable",
"age": "42",
"hiredate": "October 25, 2005",
"product": "Keyboard"
}
]

With filter criteria


%dw 2.0
output application/json
ns org http://www.mycompany.org/employees
---
payload.employees.*employee filter($.name.@age > 30) map {
fullname : $.name.firstname ++ " " ++ $.name.lastname,
age: $.name.@age,
hiredate : $.hiredate,
product : $.projects.project.product
}
Output
[
{
"fullname": "Cary Grant",
"age": "32",
"hiredate": "October 20, 2005",
"product": "Desktop"
},
{
"fullname": "Clark Gable",
"age": "42",
"hiredate": "October 25, 2005",
"product": "Keyboard"
}
]

DEBUG DATAWEAVE IN MULESOFT

Dataweave is the most used activity in MuleSoft integration and it’s too much of time to come up with a
correct dataweave. With this post we like to highlight how quickly you can debug and test your dataweave
in MuleSoft
Let’s start with debugging dataweave in MuleSoft applicaiton
if we have to test the below dataweave for input payload [1,2,3,4,5]

Add a breakpoint on transformation activity

Run the application in debug mode and call the api

Click on watch expression window and pin it, so that it will not close when u move to other window.

Now we have to make the dataweave text in single line to test it


Copy dataweave and paste in Notepad++

Select the text and press CTRL + J – this will remove the new line character from the text

Copy and test the expression in expression window to see the result

If u feel you have to change in dataweave then go back to Notepad++ and press CTRL + Z to undo the
hide new line. Make the necessary change and retest in your expression window.
Hope this will help 🙂

DATAWEAVE TIPS & GUIDELINES

Dataweave Tips & Guidelines – Here are few tips and best practices which could be useful to consider
while writing dataweave. There are plenty of operators in dataweave which can make your life easy while
writing complex dataweave transformation. Obviously the list below is not an exhaustive list, but we have
tried to cover few important aspects while writing dataweave.

DATAWEAVE TIPS
Consider the payload below for reference
{
"name": "Mulesy Mulesy",
"age": 30,
"profession": "Mulesoft",
"date": "2020-05-29T10:02:45-04:00",
"comment": "Special characters. "
}

Dealing with special characters in dataweave

If you have some special character (e.g. “, $ etc) in your payload here is how you can deal them in
dataweave using “\”.
%dw 2.0
output application/json
---
{
name: payload.name,
age: payload.age,
profession: payload.profession,
date: payload.date,
comment: payload.comment ++ "\$\$ handling special character \$\
$"
}

Pattern matching in Dataweave

if you want to validate a complex pattern in your payload, you can use power of regex in dataweave.
E.g. if you want to evaluate whether your payload.name has any number in it, here is how you can use
regex. You can use regex for any complex pattern evaluation.
%dw 2.0
output application/json
---
{
name: payload.name,
age: payload.age,
profession: payload.profession,
date: payload.date,
comment: payload.comment ++ "\$\$ handling special character \$\
$",
"regex_number_check" : payload.name contains /\d+/
}
Using static java methods of available libraries (e.g. apache) directly in Dataweave

For this you will need to add the dependency of the library in the pom file. In the script below we are using
the split method of the apache StringUtils class directly into the dataweave
%dw 2.0
output application/json
java!org::apache::commons::lang3::StringUtils
---
{
name: payload.name,
age: payload.age,
profession: payload.profession,
date: payload.date,
comment: payload.comment,
other_Value: StringUtils::split("aa-bb-cc-dd","-")
}
Result
{
"name": "Mulesy Mulesy",
"age": 30,
"profession": "Mulesoft",
"date": "2020-05-29T10:02:45-04:00",
"comment": "Special characters. ",
"other_Value": [
"aa",
"bb",
"cc",
"dd"
]
}

Creating dynamic elements or keys in an Object

if you want to add a dynamic key or a key value pair dynamically, into an object. Here is how you can
write it.
%dw 2.0
output application/json
var dynamic_element = {"dynamic_element": "dynamic element"}
var dynamic_key = "dynamic_key"
---
{
name: payload.name,
age: payload.age,
profession: payload.profession,
date: payload.date,
comment: payload.comment ++ "\$\$ handling special character \$\
$",
"regex_number_check" : payload.name contains /\d+/,
(dynamic_element),
(dynamic_key) : "Dynaimc key"
}

Creating comments in Dataweave

Comments are very helpful if you are doing some complex transformation and wants to mention the
outcome of the complex steps . Here is how you can use comments in dataweave scripts.
%dw 2.0
output application/json
var dynamic_element = {"dynamic_element": "dynamic element"}
var dynamic_key = "dynamic_key"
---
{
name: payload.name, // single line comment
age: payload.age,
profession: payload.profession,
date: payload.date,
comment: payload.comment ++ "\$\$ handling special character \$\
$",
"regex_number_check" : payload.name contains /\d+/,
/*
* dynamic key below
* dynamic element below
* */
(dynamic_element),
(dynamic_key) : "Dynamic key"
}

TimeZone handling in the dataweave

If you want to convert the time to a different timezone, you can do that as below. You can get the value of
various timezones using java!java::util::TimeZone::getAvailableIDs()
%dw 2.0
output application/json
---
{
name: payload.name, // single line comment
age: payload.age,
profession: payload.profession,
date: (now() as DateTime >> 'America/Chicago' ) as String,
comment: payload.comment
}

Adding year, month, day, hour, minutes or second to a date time

Here is how you can add or subtract date time parameters from a date time.
%dw 2.0
output application/json
---
{
name: payload.name, // single line comment
age: payload.age,
profession: payload.profession,
date_1: payload.date as DateTime + |PT1S| + |PT1M| + |PT1H| + |
P1D| + |P1M| + |P1Y|,
date_2: payload.date as DateTime - |PT1S| - |PT1M| - |PT1H| - |
P1D| - |P1M| - |P1Y|,
comment: payload.comment
}

null check in dataweave

Various operator (e.g sizeOf , “to” etc) breaks and result in null pointer exception if the input to these
operator is null. It is always useful to define default value using default operator to a variable
Consider the payload below
<employees>
<employee department="HR">HR Mulesy Mulesy</user>
<employee department="OPS">OPS Mulesy Mulesy</user>
</employees>
isEmpty(payload.employee) will result true
payload.employee == null will result true
payload.employee !=null will result false

Selectors use case in dataweave

Consider the payload below


<employees>
<employee department="HR">HR Mulesy Mulesy</user>
<employee department="OPS">OPS Mulesy Mulesy</user>
</employees>

payload.employees.*employee will result list of all employee : [ “HR Mulesy Mulesy “, “OPS Mulesy
Mulesy”]
payload.employees.&employee will result key and value of all employee : {employee: “HR Mulesy
Mulesy” , employee : “OPS Mulesy Mulesy” }
payload.employee? will result: false
payload.employee! will result: an error

Relational operator “~=” in dataweave

If you need to compare the value of two different types, this operator can come very handy. E.g. In the
script below, we are trying to compare numeric 30 with string “30”. “==” operator would compare the
types also and would result false.
%dw 2.0
output application/json
---
{
name: payload.name,
age: payload.age,
profession: payload.profession,
date: payload.date,
comment: payload.comment,
operator1 : 30 ~= "30",
operator2 : 30 == "30"
}

Iteration and aggregation over a collection in dataweave


Sometimes we need iterate through a collection and accumulate the value for every iteration. You can use
reduce function in dataweave. Details here https://mulesy.com/reduce-function/

Conditional check for an element’s inclusion in object

if you ever need to create an output where the element/s occurrence depends on a condition, here is how
you can do that in dataweave.
%dw 2.0
output application/json
var condition = 1
---
{
name: payload.name, // single line comment
age: payload.age,
profession: payload.profession,
date:payload.date,
(comment: payload.comment) if (condition !=1)
}

Add/update a key/s of an object in dataweave

If you want to add or update the value of key of an object. Here is how you can write the Dataweave . If
the key is not present in the payload, then it would add a new key to the object otherwise it would update
the existing key’s value
%dw 2.0
output application/json
---
payload ++ {
location: "India", // single line comment
}

Remove key/s of an object in Dataweave

%dw 2.0
output application/json
---
payload -- ["date","comment"]
Prepend, Append, and Remove Operators for Arrays

If you need to add, remove any elements in array; you can use ++, — operator to do the same

Formatting in dataweave

You can format a string to a particular format in dataweave. First convert the input to a desired type and
then to a String and then use {format: “#,###.###”}. E.g.
%dw 2.0
output application/json
---
{
name: payload.name,
age: payload.age,
profession: payload.profession,
date: payload.date,
comment: payload.comment,
number: 423424.978 as String {format: "#,###.0000"},
format1: now() as String {format:'yyyy-MM-dd-HH:mm'},
formtat2: 123131.3 as String {format :"0.0000" },
format3 : now() as Date as String {format: "YYYY-MM-
dd'T00:00:00Z'"}
}

Functions and it’s various use cases

We should always use functions to create a reusable piece of functionality/method. Functions can also be
created to repeat or call a feature recursively. Function are defined using “fun” attribute. Function can
accept any arguments e.g. object, collection, simple type, functions, lambdas. Functions and lambdas
(anonymous functions) can be passed as values or be assigned to variables. Here are few ways to define the
functions.

Sample payload
{
"name": "Mulesy Mulesy",
"age": 30,
"profession": "Mulesoft",
"date": "2020-05-29T10:02:45-04:00",
"comment": "Special characters. ",
"CHILD_Element1" : {
"element1" : "element1",
"child_element_2" : {
"ELEMENT2" : "element2"
}
}
}

Code Snippet.

%dw 2.0
fun fun1(user) = {
firstName: user.name,
age: user.age
}
var var1 = (user, age) -> {
firstName: user.name,
age: age
}
fun fun2(user) = do {
var age_present = (user.age) !=null
---
if(age_present == true) {
firstName: user.name,
age: user.age,
id: "1"
}
else {
firstName: user.name,
age: "default age"
}

}
fun fun3(element, func) =
if (element is Object)
element mapObject (value, key) -> {
(func(key)) : fun3( value, func)
}
else element
output application/json
---
{
name: payload.name,
age: payload.age,
profession: payload.profession,
date: payload.date,
comment: payload.comment,
funusage_1: fun1(payload),
variable_1: var1(payload, 30),
funusage_2: fun2(payload),
funusage_3: fun3(payload, (key) -> lower(key))
}
Transformation Result
{
"name": "Mulesy Mulesy",
"age": 30,
"profession": "Mulesoft",
"date": "2020-05-29T10:02:45-04:00",
"comment": "Special characters. ",
"funusage_1": {
"firstName": "Mulesy Mulesy",
"age": 30
},
"variable_1": {
"firstName": "Mulesy Mulesy",
"age": 30
},
"funusage_2": {
"firstName": "Mulesy Mulesy",
"age": 30,
"id": "1"
},
"funusage_3": {
"name": "Mulesy Mulesy",
"age": 30,
"profession": "Mulesoft",
"date": "2020-05-29T10:02:45-04:00",
"comment": "Special characters. ",
"child_element1": {
"element1": "element1",
"child_element_2": {
"element2": "element2"
}
}
}
}

Function fun1 takes object as input and outputs an object with keys firstName and age. This is a simple
function.

Function fun2 takes object as input and uses “do” attribute to create a variable in function. it assigns the
variable “age_present” to boolean true or false depending upon the value of age attribute in payload passed
as input. it then conditionally outputs the result depending upon the variable value. This function explains
how we can create variable and use them in functions

Function fun3 is basically to achieve the recursion type of feature. Here were are changing the element’s
key to lower case recursively. It accepts a payload and a function as input parameter. Here we are trying to
change all the keys of an object to lower case recursively. For recursion type of logic, you would always
need to have a if else block to exit from the recursion when you have reached to end of it.

BEST PRACTICES OR GUIDELINES

Use Custom Dataweave modules

use custom dataweave modules for re-usability across the organization. Create a file under
src/main/resources/dwmodules/common.dwl

Use the above global function as below in dataweave script

Use global variable in DataWeave

It optimizes and simplifies your DataWeave code. Since the global variables are evaluated once hence it
helps in improving the performance also.
%dw 2.0
output application/json
import * from dwmodules::common
var currentdate = getCurrentDateTimeCST()
---
{
name: payload.name,
age: payload.age,
profession: payload.profession,
date: currentdate,
comment: payload.comment
}

Use local variable in dataweave.


It simplifies your code and improves performance in case you want to further evaluate again and again.
This could be useful inside map operators, where you have to iterate over a changing collection again.
%dw 2.0
output application/json
import *from dwmodules::common
---
using (localvar1 = "pp", localvar2 = "123") {
name: payload.name,
age: payload.age,
profession: payload.profession,
date: getCurrentDateTimeCST(),
comment: payload.comment
}

Create dwl files for large resuable transformations.

Create dwl files instead of inine dataweave for reusable and long dataweave scripts. You can create a
folder like src/main/resources/dwl refer all the *.dwl files from there. Make sure to include that in
artifact.json under “exportedResources” element.

Use named parameters for key, index and value in operators which accept lambda

Always use named parameters in operator e.g. map/mapobject/filter/pluck etc for any reference to key,
value and index. e.g. use “map (employee, employee index) – > {} “ instead of “map()- > {}”. Don’t
reference using $, $$, $$$ . This would also help in correlating the elements in different maps

Use dataweave functions in DataWeave

if you are doing a repetitive task in a particular dataweave scripts, then it’s better to create functions either
global or local and refer them in the dataweave. Use global dataweave functions if the same function is
used across the multiple projects.

Please do let us know if you have any specific guidelines related to dataweave that one should follow.
Thanks and happy reading!

REDUCE FUNCTION

Reduce function is used to do any computation while iterating on an array, computation result is not lost
while iteration. it’s a very helpful function where you have to do computation on some array element.
reduce(Array<T>, (item: T, accumulator: T) -> T): T | Null
or
Array<T> reduce( (item: T, accumulator: T) -> T): T | Null
Here
Array – is the array on which we want to apply reduce function
Item
item in the input array
Refer as $
Takes 1st array item value in case acc is defined
Takes 2nd array item value in case acc is not defined
Accumulator (acc)
Store the results of lambda expression after each iteration in reduce function
Refer as $$
We can explicitly define the initial value like [2,3,3] reduce ((item, acc = “2”) → acc * item)
If initial value is not defined then it will take the value of first item of array.
Iteration
no of item in array minus 1 in case acc is not initialized
no of item in array in case acc is initialized
Lets see the use case where
acc value is not initialized
Dataweave:
%dw 2.0
output application/json
---
[2, 3] reduce ($ + $$)
Here
[2,3] – is the input array
acc -> $$ will take the 1st item value = 2 (as acc is not initialized)
$ will take the 2nd item value = 3 (as acc is not initialized)
Loop count = no of item in array minus 1 (as acc is not initialized) = 2 – 1 = 1
Acc = ($=3 + $$=2) = 5
So result will be 5
acc value is initialized
Dataweave:
%dw 2.0
output application/json
---
[2,3] reduce ((item, acc = 4) -> acc + item)
Here
[2,3] – is the input array
acc will take the initialized value = 4
item will take 1st item value = 2 (as acc is initialized)
Loop count = no of item in array (as acc is initialized) = 2
Acc = acc + item -> 4 + 2 -> 6
Acc = acc + item -> 6 + 3 -> 9
So result will be 9

DESCENDANTS SELECTOR
Works on arrays and objects and to retrieves the values of all matching key-value pairs in the sub-tree
under the selected context regardless of the hierarchical structure of the fields. Let’s see how Descendants
Selector works.
The .. selector acts on arrays and objects
Input Payload
{
"employees": {
"employee": {
"emp_name": "ram",
"address": {
"street": {
"emp_name": "john",
"employeenumber": 1234
},
"area": {
"zip": "110032",
"emp_name": "shyam"
}
}
}
}
}
Dataweave expression:
%dw 2.0
output application/json
---
{
emp_name: payload.employees..emp_name
}
Output
{
"emp_name": [
"ram",
"john",
"shyam"
]
}

EXTERNAL JAR CLASS IN DATAWEAVE

We can reuse the existing External Jar Class in Dataweave without writing the java code in dataweave
again. One of the external jar usage can be extending StringUtils method in Dataweave as currently
Dataweave doesn’t support all the String functions as Java StringUtils does
To do so we have to perform following steps
Add required dependency and shared lib tags in pom.xml
Dependency
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
Shared Library
<configuration>
<sharedLibraries>
<sharedLibrary>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</sharedLibrary>
</sharedLibraries>
</configuration>
Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>dataweave-sample</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>mule-application</packaging>
<name>dataweave-sample</name>
<properties>
<project.build.sourceEncoding>UTF-
8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-
8</project.reporting.outputEncoding>
<app.runtime>4.2.2</app.runtime>
<mule.maven.plugin.version>3.3.5</mule.maven.plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-maven-plugin</artifactId>
<version>${mule.maven.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<sharedLibraries>
<sharedLibrary>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</sharedLibrary>
</sharedLibraries>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.mule.connectors</groupId>
<artifactId>mule-http-connector</artifactId>
<version>1.5.11</version>
<classifier>mule-plugin</classifier>
</dependency>
<dependency>
<groupId>org.mule.connectors</groupId>
<artifactId>mule-sockets-connector</artifactId>
<version>1.1.5</version>
<classifier>mule-plugin</classifier>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>anypoint-exchange-v2</id>
<name>Anypoint Exchange</name>

<url>https://maven.anypoint.mulesoft.com/api/v2/maven</url>
<layout>default</layout>
</repository>
<repository>
<id>mulesoft-releases</id>
<name>MuleSoft Releases Repository</name>
<url>https://repository.mulesoft.org/releases/</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>mulesoft-releases</id>
<name>mulesoft release repository</name>
<layout>default</layout>
<url>https://repository.mulesoft.org/releases/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
Add classLoaderModelLoaderDescriptor element in
mule-artifact.json
{
"minMuleVersion": "4.2.2",
"classLoaderModelLoaderDescriptor": {
"id": "mule",
"attributes": {
"exportedPackages": [
"org.apache.commons.lang3"
]
}
}
}
Import the Class and use it in Dataweave
Dataweave
%dw 2.0
import java!org::apache::commons::lang3::StringUtils
output application/json
---
{
a: StringUtils::substring("MYSTRING",1,2)
}
or
%dw 2.0
output application/json
---
{
a: java!
org::apache::commons::lang3::StringUtils::substring("MYSTRING",1,2)
}

S-ar putea să vă placă și