Tip number 1 will be about data existence check. There are often situation that nearly the same conditions need to be checked in every line. I have seen many transformations that were really long and complex. Reading them were not only difficult but a lot of repeatable conditional checks were made. Here I will show you an example that will evolve to point where we reuse everything that was possible. As a result we should achieve more concise and readable transformation. MuleSoft is about to release new DataWeave that is why examples are both in 1.0 and 2.0.

Contract

Here is the input in XML format and expected JSON result:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <product description="Cardigan Sweater" product_image="cardigan.jpg">
    <catalog_item gender="Men's">
      <item_number>QWZ5671</item_number>
      <price>39.95</price>
      <size description="Medium">
        <color_swatch image="red_cardigan.jpg">Red</color_swatch>
        <color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
      </size>
      <size description="Large">
        <color_swatch image="red_cardigan.jpg">Red</color_swatch>
        <color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
      </size>
    </catalog_item>
    <catalog_item gender="Women's">
    </catalog_item>
 </product>
</catalog>
{
  "Product": {
    "Man": {
      "Id": "QWZ5671",
      "Sizes": 2,
      "Price": 39
    },
    "Woman": {
    }
  }
}

First approach to transformation

Below I have prepared transformation without checking if data is either provided or not. For given input my transformation will not work as DataWeave can not apply cast operator as on null value. This transformation would work perfectly fine only for input where all data is present.

In Anypoint Studio we should see message like that:

14| Sizes: sizeOf(payload.catalog.product.*catalog_item[1].*size as Array),
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Cannot coerce Null (null) to Array

Trace:
 at 'sizeOf' in (anonymous:14:11)
 at 'main' in (anonymous:4:1)

Let’s fix it.

Default value

The most easiest approach is to use default operator. Construction looks as follows

After the keyword default we put value that DataWeave engine will return if parameter turns out to be empty. In transformation below you may notice that *size is set to empty array and price is set to 0 only if corresponding parameters are empty.

DataWeave 2.0
DataWeave 1.0

And here is the output:

 
{ 
  "Product": { 
    "Man": { 
      "Id": "QWZ5671", 
      "Sizes": 2, 
      "Price": 39 
    }, 
    "Woman": { 
      "Sizes": 0, 
      "Price": 0 
    } 
  } 
} 

This is fairly similar result to expected one. The difference lies in lines 9 and 10. We would prefer to get empty Woman object without properties Sizes and Price.

Emptiness check

The other solution may be null check. In order to do this we use  conditional elements. Here is the syntax:

If the condition is not met, transformation will omit the whole element. Here is the transformation:

DataWeave 2.0
DataWeave 1.0

Using this mapping we received expected outcome. However as you may see we have a lot of repetitions. We have at least 4 additional repetition that can be omitted. How do we remove them?

Complex match

The last and most readable solution in my opinion is using match that will evaluate condition once and shorten call to properties. Here is the syntax:

Else block is not required. However when at least one condition (case) could not be met, transformation will throw an exception if else block will not be present. As you may also notice match is against context and we refer to this context further using $ variable.

Here is the transformation

DataWeave 2.0
DataWeave 1.0

Mule will check only one condition for Man and Woman section. There is a verification if payload.catalog.product.*catalog_item[0] is either an object or not in line 9 and 19. Furthermore in lines 10, 11, 20 and 21 we do note repeat the whole path to each property using $ variable.

Summary

We may omit empty elements using conditional elements with if keyword. On the other hand we may use match to check if some conditions have been met. Using match we may omit a lot of same conditional checks and hence increase readability.

DataWeave – Tip #1
Tagged on:             

2 thoughts on “DataWeave – Tip #1

  • 13/04/2018 at 12:17
    Permalink

    Thanks for taking the time to write this!
    I just wanted to add that when there’s repetition, you can also extract things into variables or functions.

    Reply
    • 23/04/2018 at 16:11
      Permalink

      Yes, it a good thought as well. Thanks 🙂

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *