Create Custom DataWeave Functions in Mule 4
In this article, we will discuss what custom modules are and why they are useful. We will also understand how to use them with a use case.
Join the DZone community and get the full member experience.
Join For FreeCustom modules in MuleSoft provide the capability to create reusable components that can be shared across multiple Mule applications. Custom modules promote the best practices of modularization and abstraction, which are essential for building scalable and maintainable integration solutions.
What Are Custom Functions?
In MuleSoft, DataWeave is a powerful expression language that is used for transforming data from one format to another. You can create custom functions in DataWeave to extend its functionality and make your transformations more modular and reusable. Custom functions in DataWeave can be defined using the `fun
` keyword. Here is an example of how you can create custom functions in DataWeave:
%dw 2.0
output application/json
var dateFormat = (data) ->
data as Date {format:"MM/dd/yyyy"}
---
{
"result": dateFormat(now())
}
How Are Custom Functions Useful?
You can define custom functions with different input and output types, and you can use them in your DataWeave scripts to modularize your transformations and make them more maintainable. Custom functions can be defined at the top level of your DataWeave script or in an external module that can be imported when needed.
Use Case
Goal
To achieve reusability of DataWeave scripts using custom modules.
Consider a scenario where an organization has a requirement to develop a Mule application that needs to respond with a with some default headers. Instead of recreating the same DataWeave logic for each endpoint with the API, a custom DataWeave script is created with a custom function.
Below is the Mule application, where the user needs a response with JSON payload and default headers.
Flow
Created a Mule application, as shown in the above image. Add a listener config with HTTP configuration.
Add a transform message to create a variable 'requestHeaders
' which takes required headers from the request, as shown below.
Create a folder 'dwl
' under the path src/main/resources and externalize the DataWeave script to an external file.
Create a custom function and externalize it to the dwl folder, as shown below. This function will take 'payload
' and 'requestHeaders
' as arguments and build response payload.
Import custom function into DataWeave script. We use ::
to import a file to the DataWeave script and add the function below. We are passing 'payload
' and 'requestHeaders
' as arguments to the function.
Application Details
Below is the XML code of a sample mule application for testing.
Flow
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="5c589f20-d7b2-4250-b0ba-fe15b836b709" >
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<flow name="dw-custom-functions-apiFlow" doc:id="801d12ba-8c89-449c-b9ec-4a41b3fe318e" >
<http:listener doc:name="Listener" doc:id="5ad6a38c-315d-42bc-bf80-1f8b4bbd2c55" config-ref="HTTP_Listener_config" path="/api/test" outputMimeType="application/json" allowedMethods="POST"/>
<ee:transform doc:name="vars: requestHeaders" doc:id="348d7711-fdf9-423d-8df4-ba5e46e63be2" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
---
payload]]></ee:set-payload>
</ee:message>
<ee:variables >
<ee:set-variable resource="dwl/request-headers.dwl" variableName="requestHeaders" />
</ee:variables>
</ee:transform>
<ee:transform doc:name="response" doc:id="9ee3c899-ec8a-4721-8cf6-a20c422b622d" >
<ee:message >
<ee:set-payload resource="dwl/response-format.dwl" />
</ee:message>
</ee:transform>
</flow>
</mule>
DataWeave Files
Variable: 'requestHeaders
'
%dw 2.0
output application/json
---
{
sourceName : attributes.headers.'source-name',
sourcekey: attributes.headers.'source-key',
correlationId : attributes.headers.'x-correlation-id',
apiType : attributes.headers.'api-type',
apiId : attributes.headers.'api-id',
startDateTime : now()
}
Custom Function: 'response.dwl
'
%dw 2.0
fun finalResponse(value, requestHeaders) = {
"headers": {
"source-name" : requestHeaders.'sourceName',
"source-key": requestHeaders.'sourcekey',
"correlation-id" : requestHeaders.'correlationId',
"api-type" : requestHeaders.'apiType',
"api-id" : requestHeaders.'apiId',
"start-datetime": requestHeaders.'startDateTime',
"end-datetime": now(),
"time-elapsed": (now() - requestHeaders.'startDateTime') replace "PT" with "",
"status": "Success"
},
result: value}
Response Payload:
%dw 2.0
import dwl::response
output application/json
---
response::finalResponse(payload,vars.requestHeaders)
Endpoint Details
Url: http://localhost:8081/api/test
HTTP Method: POST
Curl request:
curl --location 'http://localhost:8081/api/test' \
--header 'source-key: Sample Key' \
--header 'source-name: Sample Source Name' \
--header 'x-correlation-id: Sample Correlatin Id' \
--header 'api-type: TEST API' \
--header 'api-id: TEST ID' \
--header 'Content-Type: application/json' \
--data '{
"message" : "requestBody" }'
Response:
Summary
In this article, we have learned what custom functions are, their importance, and how to use them. We have seen how Custom DataWeave functions provide flexibility and customization options, allowing developers to tailor data transformations according to their specific business requirements, ultimately enhancing the efficiency and effectiveness of data integration processes.
Opinions expressed by DZone contributors are their own.
Comments