Ask Sawal

Discussion Forum
Notification Icon1
Write Answer Icon
Add Question Icon

How to use dwl file in mule 4?

5 Answer(s) Available
Answer # 1 #

Please find all the blogs of this series below:

This read will take you through the best practices, tips and tricks while writing Dataweave in your Mule applications. This would also help you in:

While writing a simple dwl seems straightforward, one should also note that with the complexity of the script increasing, so does the effort required to make changes. Let me also warn you that Maintaining common functionalities across different dwls can be a challenge too.

WRITING IN FILES

By default, the transform message component writes all the data we’ve script directly in the configuration XML file. This experiences multiple disadvantages such as:

All these problems can be overridden by writing the dwl script in a dedicated file which gets stored in src/main/resources. Anypoint studio gives an option to do this as shown in the below image.

DWL file written in such a way should be organized into use-case specific folders inside src/main/resources/dwl and be named appropriately reflecting the purpose they serve.

DEFINING METADATA

Metadata should consistently be defined when using a transform message component. Defining metadata enjoys the following advantages:

The image below shows a sample of the above-mentioned points when put to use.

WRITING FUNCTIONS

One of the most convenient ways to process complex scenarios in dataweave is to write functions in dwl. When written in script, this complex processing can be used only once, but when you move it to a function, you can use it as many times as required throughout your script. Functions in DWL offer a straightforward way of passing a particular set of parameters and obtaining the desired output in a reusable manner which makes much more sense. In dataweave functions are also first citizens just like objects and this lets to pass functions as parameters to other functions.

In the below example, you can see how writing a function for something as simple a remove special chars can reduce the effort needed when any changes are required such as replacing a diverse set of special chars when compared to writing the same logic multiple times.

Something that should be paid attention to in the above examples is that functions can be called either in the header part or in the script directly, but to use the output of a certain function in the script, a variable has to be created which can hold the output of the called function.

CREATING VARIABLES

Creating variables promotes reusability and helps in better maintainability. The most common usage of variables are:

Sometimes a particular transformation can be too complex and writing a bunch of those in the script may just make things look messy and will not communicate the intention to the next developer. Writing complex logic in a script also increases the probability of syntax and logical errors while trying to modify the script. Declaring a variable and defining logic there makes the code look clean, less error-prone and increases the maintainability.

There can be situations where a particular component in the incoming payload gets used at several places, e.g. address extraction or just a key whose path is prone to change. It’s always better to store such keys  in dwl variables and use the variables in the script so that any change to them can be done at a single point.

In the above example, there are two variables, custAddressPath which stores the long path to the customer address object to make sure any change to the customer address object path will result in changing only one line in the entire code.

The second variable created is custAddress which joins all the components of the customer address object and puts them together in a readable format. Since this logic is needed at two places both for the customer’s billing address and delivery address, this variable reduces the lines of code by storing them in a single place.

MAKING CHANGES AT SCRIPT LEVEL

There are certain situations where a particular change, check or function has to be applied to the entire payload, but writing everything line by line might not make sense. Although for complex scenarios there are recursive functions to traverse through the payload, there some features in dataweave that let you apply e.g. a null check to the entire payload with just one line of code.

%output application/xml skipNullOn="everywhere"

USING DWL FILES EVERYWHERE ELSE

Writing dataweave script in files has another advantage, dwl files can not only use be used in transform message components but in any mule component that allows using of dataweave(which is almost everything in Mule 4). If a dwl file is stored in src/main/resources, you can use ${file::filename} syntax to send the script in a dwl file through any XML tag that expects an expression. See the example in HTTP:body:

It’s always easier if common functions can be maintained centrally so that when a change comes through, you need to modify code only in one place. Just like how you can include different DWL libraries(Mule provided) in your DW script, you can also include a custom written DW file in your script to reuse your functions. The idea is to identify all the common functions that apply to more than one script in your application and store them in a single file and now you can include this common file in any DW in your application and use the functions.

e.g. a function is written in a file dwl/modules/functions.dwl like this:

And can be used like this in the implementation:

IMPORTANCE OF PARAMETERIZATION

Any static data which needs to be used in a dwl script and can be stored as property must always be stored as a property. Whether it is looking for a particular string from a set of values or an exact string match, writing this static data as a property always helps in changing or updating conditions on the go without having to touch the dwl script. Such properties are usually not environment-dependent and can be stored in dedicated dwl properties files which span across all environments the application will be deployed to.

After being done with an exact string match, let’s see how to deal with matching an incoming value against a set of values.

Sometimes a single key-value pair storing is just not enough and the property storage becomes complicated. Although this is not the best way but a JSON can be stored as a string in a property file and used in a dwl script in the following way.

With all the benefits and advantages of dataweave, there is still a major hiccup when it comes to writing dataweave while developing an application. Anypoint studio allows dynamic viewing of working of dataweave code using the preview functionality, but this comes with the problem of Anypoint Studio getting stuck. While Anypoint studio is not very high performing in general, it chokes when dataweave(Transform Message component) is used. Although there is no fixing Anypoint Studio soon, there is indeed an alternative approach to this, called Dataweave playground.

Dataweave playground is a docker image that lets you write and run dataweave right out of a browser. This can be found here, https://hub.docker.com/r/machaval/dw-playground It is very easy to spin up a local/cloud instance of this image but there is a free version of this is hosted already by Mulesoft for free to practice and have fun, which can be found here: https://developer.mulesoft.com/learn/dataweave This comes along with all the dataweave documentation, so next time there is an issue with Anypoint Studio or you just don’t want to open it to write code, just go here.

https://docs.mulesoft.com/mule-runtime/4.3/dataweave-create-module

[4]
Edit
Query
Report
Ove Nicolaou
Showrunner
Answer # 2 #

GitHub repository with the Mule Project can be found at the end of the post.

Some days ago, I started using this great functionality in DW 2.0, and I faced some challenges while creating the code, so I figured I’d write a blog post about my experience.

MuleSoft’s documentation offers a great explanation of how to create these custom modules. One problem that I couldn’t find how to solve in the documentation was how to correctly load a property from the properties file into the custom module.

If you’re not familiar with custom modules, don’t worry, I got your back ;)

For this post, I’ll explain what a custom module is, why you would want to use it, some examples on how you can use it, and finally, how to load properties into this module.

First of all, let me tell you what a regular Module is in DW 2.0: from MuleSoft’s documentation, “DataWeave 2.0 functions are packaged in modules. Functions in the Core (dw::Core) module are imported automatically into your DataWeave scripts.”. Yes, all those functions that you use in your DW scripts, come from the Core module. Functions like ++, flatten, map, joinBy, that you may use on your day-to-day, come from Modules, you just don’t need to explicitly import them into your script. Other developers may call them libraries however in DW 2.0 they are called modules.

Mule offers a wide choice of modules that you can use to transform and manipulate your data, like the Arrays module, the Strings module, the Objects module, even Binaries or Tree. You don’t need to know how all of these work, just understand the basic meaning of a module, which is: functions created by MuleSoft that can be reused into your DW scripts.

Custom Modules are pieces of code that can be stored into an external file, in order to be reused in other parts of the Mule application. These are not created by MuleSoft, but by yourself, or your company.

Here is an example to illustrate why Custom Modules are useful: you just created a new function that will join an array of words into a complete sentence. Like this:

As you can see, we are using the joinBy function in the code to select which character we want our words to be separated by, in our complete sentence. If we were to change our code from joinBy “ “ to joinBy “-”, our final output would be "Hello-ProstDev-:)" instead.

If this piece of code, to create a complete sentence from an array of words, was used in several parts of your application, it would be a good idea to create a function inside a Custom Module to store this code. Then just reference that function from anywhere else in the rest of the app; instead of having to copy and paste this code into each part where you need to use it.

Let’s see how we can create this module for our Mule Application:

Of course, this is a very simple example, it’s only one line of code. You may think that we generated even more code by doing this than by copying and pasting the code in several scripts. Fair enough. But, imagine what would happen if you suddenly decide to change the functionality? You’d have to go to each of the DW scripts and manually change every single line of code. If you have a custom module setup, you’d only have to change the function from the Custom.dwl file, and all the scripts referencing it will automatically have the new functionality. Copy and Pasting means you have to go through and change each one but with this method it's done automatically - for graphic designers out there it's like the embed feature in photoshop.

Remember that character we used after the joinBy function? What if we wanted that character to be in a properties file, instead of hardcoded (added directly) in our script? Can we do that when using Custom Modules? Yes, we can!

I already have my “default-properties.yaml” file created under “src/main/resources”, with one property that I decided to name “joinByChar”

We can go back to our “Custom.dwl” file and change the script to reference this property instead of hardcoding the character there. You may already know that the properties can be used in your Mule Application by using either the ${ } or the p(‘ ‘) syntax. However, if you try to use any of these from a Custom Module, DataSense will send you back an error (at least for Mule Runtime version 4.3.0 and Anypoint Studio version 7.5.0).

I was losing my mind trying to search in the Mule Docs or in the Mule Forums how I could import a property from my custom module. In the end, one of the Mule Ambassadors, Manish Yadav, was able to point me in the right direction. Remember at the beginning of this post, when I explained that all the DataWeave functions come from a module that is created by MuleSoft. Well, when you use this function: p(‘my-property’) to load a property into the script, do you know which module it comes from? It comes from the Mule module!

We can rewrite our function like this:

Aaaaand… Magic! We have our same output, but now we’re using an external property to generate the final sentence.

This way we can change our property joinByChar right from the default-properties.yaml file and we do not need to touch the code to select a new character.

Feel free to download the Mule project from our github repository and give it a try! Maybe you get it to work with another syntax :) If you do, don’t hesitate to leave a comment and let me know about it. I’d love to keep learning more DataWeave functions.

Let’s do a quick recap on what we learned with this post:

Special thanks to Manish for this tip and for being so quick to respond to my messages!

Stay tuned for more DataWeave tips and tricks.

Prost!

-Alex

ProstDev GitHub - Custom Modules DW 2.0

[3]
Edit
Query
Report
Andreas Tripathy
SUPERVISOR PIGMENT MAKING
Answer # 3 #
  • In the Package Explorer window src/main/mule (Flows) folder, navigate to your flow's .
  • In the Mule Palette view, select the HTTP Listener source and drag it onto the canvas.
  • Set the Path field to /test .
[3]
Edit
Query
Report
Nubendu Fadnis
WIRE MESH FILTER FABRICATOR
Answer # 4 #

Custom Dataweave Function Using Custom Module

In addition to using the built-in DataWeave function you can also create and use custom modules and mapping files. You write modules and mapping files in a DataWeave Language (.dwl) file and import into your Mule app through DataWeave scripts in Mule components. Both modules and mapping files are useful when you need to reuse the same functionality or feature over and over again.

Custom modules can define functions, variables, types, and namespaces. You can import these modules into a DataWeave script to use the features.

Custom mapping files are a type of module that contains a complete DataWeave script that you can import and use in another DataWeave script or reference in a Mule component.

Note: Unlike a typical DataWeave script or mapping file, a custom DataWeave module cannot contain an output directive, body expression, or the separator (—) between header and body sections.

Create a project in anypoint studio, configure the listener and add the modules folder under src/main/resource to keep the .dwl

Create the .dwl and define the custom function

Create the Transform message and invoke the custom function from Dataweave as shown below

Dataweave

Deploy the project and test from soap ui

Sample Application: customdataweave sample application

Soap UI Project: Sample soap ui project

[1]
Edit
Query
Report
Jaswinder Singh
COUNTER MOLDER
Answer # 5 #

A .dwl file for custom functions is created in src/main/resources under a folder called module.

The custom functions file is under the module folder, so while importing, we need first to mention the folder name followed by the scope resolution operator (::) and then the file name.

We are just importing the file, so we need to mention the file name followed by the scope resolution operator (::) then the function while calling the function.

Calling only one function:

Calling both the functions:

We use an asterisk (*) followed by from keyword, which means import everything from the file to import everything.

Since we are importing everything this time, we don’t need to mention the file name while calling the functions, or else it will throw an error.

Without file name:

With file name:

[1]
Edit
Query
Report
Ueli Grashin
Sculptor