The DataWeave CLI

How to use DataWeave code in your Bash scripts.

The DataWeave CLI

Overview

On a previous project I needed to parse and query JSON from the command line using Bash. I didn't have much prior experience with Bash so I wasn't sure where to start. A quick Google search helped me find jq. jq is great, and it fit my needs really well, but from my MuleSoft experience I knew about DataWeave. Dataweave could do everything that jq could do with JSON, plus deal with XML, CSV, etc, all using the same language. I think I actually said to my teammate, "DataWeave would be perfect for this but we can't get to it from the command line." As I later found out, you can.

DataWeave CLI

The DataWeave CLI (github) allows you to use DataWeave from Bash. Here's an example:

echo '{"hello":"world"}' | dw 'output application/xml --- { root: payload }'

<?xml version='1.0' encoding='UTF-8'?>
<root>
  <hello>world</hello>
</root>

Using Files as Input

If you have a file you can feed it to dw's -input parameter:

echo '{"hello": "world"}' >> test.json
dw -input payload test.json 'output application/xml --- { root: payload }'

If you have multiple files, you can use the -input parameter more than once:

echo '{"goodbye": "space"}' >> test2.json
dw -input file1 test.json -input file2 test2.json 'output application/xml --- { root : { f1: file1, f2: file2 } }'

Using Files as Output

You can write the output to a file in one of two ways. You can use the -output parameter:

dw -output result.xml 'output application/xml --- { root: { hello: "world" } }'

Or you can use > (overwrite) and >> (append) to direct STDOUT to a file:

dw 'output application/xml --- { root: { hello: "world" } }' > result.xml

Gotchas

If you're piping input into dw, you will need to specify the input mimetype. If you don't dw will try to parse it as application/json by default.

No input mimetype specified:

cat data.xml | dw 'payload.root'

Unexpected character '<' at payload@[1:1] (line:column), expected false or true or null or {...} or [...] or number but was , while reading `payload` as Json. 
...

Correct:

cat data.xml | dw 'input payload application/xml --- payload.root'

{
  hello: "world"
}

Notice the output isn't application/xml. It's application/dw which is how DataWeave is representing the data in terms of its own data structures. To get XML output, we need to specify the output directive:

cat data.xml | dw 'output application/xml input payload application/xml --- payload.root'

<?xml version='1.0' encoding='UTF-8'?>
<hello>world</hello>

Conclusion

Being able to use DataWeave from the terminal is a huge affordance if you already know how to use the language. I can think of a few good uses, one of them being writing some quick and dirty Bash scripts to test an API. Before, you'd need multiple tools to parse JSON, XML, CSV, etc. You probably wouldn't typically do this in Bash, but maybe one day you'll find yourself in a pinch :)