DataWeave は、MuleSoft(参考 MuleSoftとは?)が提供するデータ変換とスクリプト言語です。Mule 4(Anypoint Platformを含む)環境では標準で組み込まれており、JSON、XML、CSV、Javaオブジェクト、さらには複数のフォーマットに対して柔軟かつ便利な変換機能を提供します。
MuleSoftでは、このDataWeaveをうまく活用することで様々な処理を実現することが可能になります。
とはいえ、Dataweaveを集中的に学ぶ機会も限られているのが現実。そこでこのページでは、Dataweaveとは何か?から始め、Dataweaveを利用した簡単なコーディング(少なくともコードを読むことができる)が可能になるようにDataweaveの構文ルールを1からわかりやすく解説します。
DataWeaveの特徴
まずは、簡単にDataWeaveの特徴をお示しします。
- 宣言的(Declarative)なスタイル
従来の命令型スタイル(if/for/whileなど逐次処理)とは異なり、「入力データをどのように出力データへマッピングするか」を宣言的に書くことで、表現力豊かなデータ変換を少ないコード量で実現します。 - 各種データ形式に対応
JSON、XML、CSV、Javaオブジェクト、YAMLなど、多様な形式との相互変換に対応します。Mule Flow内ではtransform
コンポーネントでDataWeaveスクリプトを記述し、入力から出力への変換を定義します。 - 関数型言語としての特性
DataWeaveは変換を行うために関数型言語の要素を取り入れており、副作用が少なくテスト可能で読みやすいコードを書くのに適しています。 - Mule 4以降でメイン言語として利用
Mule 3まではMule Expression Language (MEL)とDataWeave 1.0の2本立てでしたが、Mule 4以降はDataWeave 2.0がメイン。大幅に強化された機能が用意されています。
- QTransformコンポーネントとは・・・?
- A
MuleSoftのフローでデータ変換を実行するためのコンポーネントです。主に以下の役割を果たします。
- データフォーマットの変換
JSON、XML、CSV、Javaオブジェクトなど、異なる形式間の変換を行います。 - DataWeaveスクリプトの実行
Transformコンポーネント内でDataWeaveを使い、データを柔軟に加工・整形します。 - 入力と出力のマッピング
フロー内のペイロード(payload
)や属性(attributes
)を操作し、次の処理へ渡すデータを定義します。
- データフォーマットの変換
DataWeaveの基本構文
DataWeaveスクリプトの基本構造
DataWeaveスクリプトは大きく以下の3つのセクションで構成されます。
%dw 2.0 output application/json --- payload
- 宣言セクション(Directive)
%%dw 2.0
のようにバージョンを示します。また必要に応じてimport
等(※後述)を記述します。 - 出力形式(Output)の指定
output application/json
など(※後述)で、変換結果のメディアタイプを指定します。 - 変換式(Body)本体
---
の後に変換処理を記述します。ここに式(式言語)を書いていきます。
サンプルコード 最もシンプルな例
%dw 2.0 output application/json --- payload
上記の場合、入力(payload
)がそのままJSONとして出力されます。
Dataweaveのバージョンについて
DataWeave 1.0:
- Mule 3で導入されたバージョン。
- 構文が異なる: 1.0では少し冗長で、2.0ほどの柔軟性がありません。
output application/json ---
などのセクション構成は似ていますが、詳細な書き方に差異があります。
DataWeave 2.0:
- Mule 4で採用。現在の主要バージョン。
- 機能強化: より宣言的なスタイル、追加の高階関数(
flatMap
やreduce
など)、モジュールの柔軟な利用。 - JSON、XML、CSV、Javaオブジェクトなどのフォーマット間変換が簡易化。
Mule 4を使用する場合、DataWeave 2.0がデフォルトで使われます。1.0はMule 3専用のため、2.0を学習・利用するのが推奨されます。
Script Header の各種オプション
output application/json skipNullOn="everywhere"
Nullを出力から除外するといった細かいオプション指定が可能です。output application/xml indent="true"
XML出力を整形するなど、各種メディアタイプに応じたオプション設定ができます。
コメント
- 行コメント:
// ここはコメント
- ブロックコメント:
/* ここはブロックコメント */
%dw 2.0 output application/json --- /* ブロックコメント: 以下では、サンプルデータの操作と コメントの使い方を示します。 */ var sampleData = [1, 2, 3, 4, 5] // 行コメント: 配列データを定義 { // 配列の要素を2倍にする doubledValues: sampleData map (item) -> item * 2, /* 条件に基づくフィルタリング: 2倍した値が6以上の場合のみ取得 */ filteredValues: sampleData map (item) -> item * 2 // 要素を2倍 filter (item) -> item >= 6, // フィルタリング // 結果の概要 summary: { originalSize: sizeOf(sampleData), // 元のデータの要素数 filteredSize: sizeOf(sampleData filter (item) -> item * 2 >= 6) // フィルタリング後の要素数 } }
データ型とリテラル
DataWeaveで扱える代表的な型・リテラルは以下の通りです。
スカラー型
- Qスカラー型とは?
- A
単一の値を表すデータ型のこと。複雑な構造を持つ配列やオブジェクトとは異なり、最小単位のデータ型と考えればOK。
%dw 2.0 output application/json --- { stringExample: "Hello, DataWeave", // String numberExample: 123, // Number booleanExample: true, // Boolean nullExample: null, // Null dateExample: |2023-01-01| // Date }
スカラー型 | 説明 | サンプル |
---|---|---|
String | 文字列型 | "Hello" |
Number | 数値型(整数・小数) | 42 , 3.14 |
Boolean | 真偽値型(論理型) | true , false |
Null | 値が存在しないことを示す型 | null |
Date | 日付型(日時を含む場合もあり) | 2023-01-01 |
ポイント DataWeaveの型システムは動的型付け
DataWeaveは、データ型を明示的に宣言する必要がない動的型付けの仕組みを持っています。つまり、変数やデータの型は、DataWeaveが自動的に解釈して適切な操作を適用します。
%dw 2.0 output application/json --- { inferredString: "Hello", // Stringとして認識 inferredNumber: 123, // Numberとして認識 inferredBoolean: true, // Booleanとして認識 inferredNull: null // Nullとして認識 }
ポイント 必要に応じて明示的に型を指定
%dw 2.0 output application/json --- { explicitNumber: "123" as Number, // StringをNumberに変換 explicitString: 456 as String // NumberをStringに変換 }
as
演算子で型変換を行います。DataWeaveでは型変換が明示的に行えるため、操作の意図が明確になります。
配列 (Array)
- 配列は
[ ]
で表します。["apple", "banana", "orange"]
- ネストする場合:
[1, 2, ["nested", "array"], 4]
%dw 2.0 output application/json --- { // 元の配列 originalArray: [1, 2, 3, 4, 5], // 結果: [1, 2, 3, 4, 5] // 配列の各要素を2倍に変換 doubledValues: [1, 2, 3, 4, 5] map $ * 2, // 結果: [2, 4, 6, 8, 10] // 偶数のみを抽出 evenNumbers: [1, 2, 3, 4, 5] filter $ mod 2 == 0, // 結果: [2, 4] // 最初の3つの要素を取得 firstThree: [1, 2, 3, 4, 5][0 to 2], // 結果: [1, 2, 3] // 配列内で各要素に対してインデックスも使用して新しい形式に変換 indexedValues: [10, 20, 30] map (value, index) -> { index: index, value: value } // 結果: [{"index": 0, "value": 10}, {"index": 1, "value": 20}, {"index": 2, "value": 30}] }
オブジェクト (Object)
DataWeaveのオブジェクトは、キーと値のペアで構成されるデータ構造です。本質的には、JSONのオブジェクトと同じ概念で、データを構造化して整理するために使われます。
- オブジェクトは
{ }
で表し、キーと値をペアで記述。
{ "name": "Taro", "age": 20 }
キーに変数などを利用したい場合はダブルクォートやバッククォートを使わずに直接書くこともできます(ただし特殊文字を含む場合はクォート必須)。
オブジェクトの値にはスカラー型、配列、他のオブジェクトをネスト可能です。
{ user: { name: "Taro", age: 25 }, roles: ["admin", "editor"] }
Date/Time型
- DataWeaveには日時型リテラルがあります。
- 例:
|2023-01-01|
はDate、|2023-01-01T12:34:56|
はDateTimeなど
- 例:
- 内部的には
java.time
のAPIを活用して処理されます。
%dw 2.0 output application/json --- { // 現在の日付と時刻 currentDateTime: now(), // 現在の日付のみ currentDate: now() as Date, // 現在時刻をフォーマット (例: yyyy/MM/dd HH:mm:ss) formattedDateTime: now() as String {format: "yyyy/MM/dd HH:mm:ss"}, // 日付文字列をDate型に変換 stringToDate: "2025-01-21" as Date, // Date型に日数を加算 datePlus5Days: |2025-01-21| + |P5D|, // 5日を加算 (P5Dは期間のISO 8601表記) // DateTime型の差分計算 daysBetween: daysBetween(|2025-01-21|, |2025-01-26|) }
変数と命名
変数宣言
DataWeaveでは、var
キーワードを使用して変数を宣言し、後で使用することができます。スクリプトのHeaderか、Bodyの任意の位置で宣言できますが、スコープに注意しましょう。
%dw 2.0 output application/json --- var greeting = "Hello" var year = 2025 { message: greeting ++ " DataWeave!", currentYear: year } // ++ は文字列の連結演算子 //
letブロック内での変数宣言
スクリプトの中で部分的な計算に利用する変数を宣言するときにはlet
ブロックを使います。
%dw 2.0 output application/json --- { result: do { var x = 10 var y = 20 --- x + y } }
do { ... }
ブロック(旧称do
ブロック)内でvar
を使って変数を定義し、ブロックの最後の式を返り値として利用できます。
関数
関数の定義
DataWeaveではfun
キーワードを使用して関数を定義できます。関数は基本的に不変(Immutable)な引数をとり、副作用がない形式で記述が可能です。
fun 関数名 (引数1: 型, 引数2: 型 = デフォルト値, ...) : 戻り値の型 = 式
fun
: 関数を定義するキーワード。- 関数名: 任意の識別子(アルファベット、数字、アンダースコアで構成)。
- 引数:
- 引数名と型を指定(例:
x: Number
)。 - 必要に応じてデフォルト値を設定可能(例:
y: Number = 10
)。
- 引数名と型を指定(例:
- 戻り値の型(省略可能):
- 関数が返すデータの型を指定。
- 式:
- 関数のロジックを記述。最後の評価結果が返り値となる。
%dw 2.0 output application/json --- fun add(a, b) = a + b fun greet(name) = "Hello " ++ name { sum: add(5, 7), greeting: greet("DataWeave") }
ポイント: 関数は式として利用でき、変数へ格納したり、ほかの関数に渡したりできます。
引数の型指定
DataWeave 2.0 では任意で引数や戻り値に型を指定できます。指定しない場合は動的に解釈されます。
fun add(a: Number, b: Number): Number = a + b
ローカル関数とグローバル関数
- スクリプトヘッダに宣言するとグローバル関数として使用できます。
do { }
ブロック内で宣言すれば、スコープ内限定のローカル関数として使用可能です。
条件分岐とパターンマッチ
if ... else
DataWeaveでも一般的な条件分岐としてif ... else
が使えます。
if 条件式 then 真の場合の値 else 偽の場合の値
if
: 条件式の開始キーワード。- 条件式:
true
またはfalse
を返す式を記述。例:x > 10
。 then
: 条件がtrue
のときに評価される値。else
: 条件がfalse
のときに評価される値。
%dw 2.0 output application/json --- fun checkNumber(n) = if (n > 0) "positive" else if (n < 0) "negative" else "zero" { result1: checkNumber(10), result2: checkNumber(-5), result3: checkNumber(0) }
%dw 2.0 output application/json --- { ageCategory: if payload.age >= 18 then "Adult" else "Child" } // 入力例: {"age": 20} -> 出力: {"ageCategory": "Adult"} // 入力例: {"age": 15} -> 出力: {"ageCategory": "Child"}
match演算子(パターンマッチ)
DataWeaveにはパターンマッチングを使う機能があります。これを使うと、値や型に応じた複雑な分岐をシンプルに書くことができます。
value match { case 条件1 -> 処理1, case 条件2 -> 処理2, ... else -> デフォルト処理 }
value
: マッチ対象の値。case 条件 -> 処理
: 条件に一致した場合の処理。else -> 処理
: どの条件にも一致しない場合の処理(オプション)。
%dw 2.0 output application/json --- fun matchType(value) = value match { case is Number -> "これは数字" case is String -> "これは文字列" case is Array -> "これは配列" else -> "それ以外" } { testNumber: matchType(42), testString: matchType("Hello"), testArray: matchType([1,2,3]), testOther: matchType({ key: "value" }) }
case is Number
のように型判定が可能です。- 値そのものをパターンとして指定することもできます。
%dw 2.0 output application/json --- fun matchValue(value) = value match { case 0 -> "ゼロです", case 1 -> "ワンです", case -1 -> "マイナスワンです", else -> "その他の値です" } { result1: matchValue(0), result2: matchValue(1), result3: matchValue(-1), result4: matchValue(5) }
イテレーションと高階関数
高階関数は「関数を操作する関数」であり、配列やオブジェクトのようなデータ構造を柔軟に操作するための重要なツールです。DataWeaveのデータ変換でよく利用されるので、特にmap
やfilter
のような典型例を理解しておくと便利です!
map
配列あるいはオブジェクトに対して要素ごとに処理を行い、変換した結果を返すのがmap
です。
array map (item, index) -> 式 /* [1, 2, 3] map (item, index) -> item * index // 結果: [0, 2, 6] */
配列の例
%dw 2.0 output application/json --- ["apple", "banana", "orange"] // 各要素に対して処理 map (item, index) -> { fruit: item, index: index }
map (item, index) -> ...
の形で、要素とインデックスを引数として受け取れます。
オブジェクトの例
%dw 2.0 output application/json --- { a: 1, b: 2, c: 3 } mapObject (value, key) -> (key ++ "_value") : value * 2
mapObject (value, key) -> ...
を使うと、オブジェクトを別の形に変換できます。上記例ではキーを変えて値を倍にする処理をしています。
filter
配列やオブジェクトの要素を条件に基づいて絞り込み(フィルタリング)します。
array filter (item, index) -> 条件式
array
: 操作対象の配列。item
: 現在の要素。index
: 現在の要素のインデックス(省略可能)。条件式
: 各要素を絞り込むための条件(true
を返す要素が結果に含まれる)。
%dw 2.0 output application/json --- [1, 2, 3, 4, 5] filter (item) -> item % 2 == 1 // 上記は奇数だけをフィルタリングします。//
reduce
配列の要素を1つに集約(畳み込み)するときに用います。初期値と畳み込みロジックを指定します。
%dw 2.0 output application/json --- [1, 2, 3, 4, 5] reduce (item, accumulator = 0) -> accumulator + item // 例では配列の合計値を求めています。//
その他の高階関数
pluck
: オブジェクトからキー・値・インデックス(またはキー)を取り出して配列に変換flatMap
: map後の配列をフラットに結合distinctBy
: ユニークな要素抽出
など多数の高階関数が用意されています。
主要な演算子・機能
オブジェクトのスプレッド・結合
DataWeaveではオブジェクトのマージや配列の連結を簡単に行えます。
オブジェクトの結合
%dw 2.0 output application/json --- var person1 = { name: "Taro", age: 20 } var person2 = { age: 25, city: "Tokyo" } --- person1 ++ person2 /* { "name": "Taro", "age": 25, "city": "Tokyo" } */
同じキーがある場合は右側が優先されます(例:ageが25になる)。
配列の結合
%dw 2.0 output application/json --- [1, 2, 3] ++ [4, 5, 6] // 配列の場合は単純に連結します: [1,2,3,4,5,6] //
オブジェクトの破壊的パターン(Destructuring)
オブジェクトのキーを展開してローカル変数として取り出すことができます。
%dw 2.0 output application/json --- fun getPersonInfo(person) = // { name, age, city = "Unknown" } でpersonのキーを抜き出す person match { case { name, age, city = "Unknown" } -> "Name: " ++ name ++ ", Age: " ++ age ++ ", City: " ++ city else -> "No match" } getPersonInfo({ name: "Hanako", age: 23 })
city = "Unknown"
は、キーcity
が存在しない場合にデフォルト値として"Unknown"
を割り当てる書き方です。
when ... otherwiseによる条件生成
オブジェクトのフィールドを生成するときに条件分岐を使う場合、when ... otherwise
を活用するとスッキリ書けます。
%dw 2.0 output application/json --- { discount: (payload.price > 1000) when true else 0, category: "premium" when (payload.price > 500) else "standard" }
各種フォーマットの入出力
JSONの読み書き
- 読み取り:
input application/json
でペイロードをJSONとして解釈。 - 書き出し:
output application/json
で結果をJSONとして出力。
%dw 2.0 output application/json --- payload // JSON形式の入力をそのまま出力
XMLの読み書き
- 読み取り:
input application/xml
- 書き出し:
output application/xml
XML入力例
<book> <title>DataWeave in Action</title> <author>John Doe</author> </book>
DataWeaveで扱うとオブジェクトに変換されます。
{ "book": { "title": "DataWeave in Action", "author": "John Doe" } }
XML出力例
%dw 2.0 output application/xml --- { book: { title: "DataWeave in Action", author: "John Doe" } }
book
がルート要素となります。
CSVの読み書き
- 読み取り:
input text/csv separator=","
- 書き出し:
output text/csv
CSV入力例
name,age,city Taro,20,Tokyo Hanako,25,Osaka
DataWeaveで扱うと配列のオブジェクトとして解釈されます:
[ { "name": "Taro", "age": "20", "city": "Tokyo" }, { "name": "Hanako", "age": "25", "city": "Osaka" } ]
CSV出力例
%dw 2.0 output text/csv --- [ { name: "Taro", age: 20, city: "Tokyo" }, { name: "Hanako", age: 25, city: "Osaka" } ]
これが下記のようなCSVになる:
name,age,city Taro,20,Tokyo Hanako,25,Osaka
その他の形式
- YAML なども同様に扱えます。(
input application/yaml
,output application/yaml
) - Java オブジェクト (上級者向け): Mule Flows でJavaコンポーネントなどを使う場合に、DataWeaveでJavaオブジェクトに直接アクセスすることもできます。
モジュールと拡張機能
モジュールのインポート
DataWeave 2.0 では import
構文を使用して、外部のモジュールやユーザー定義モジュールを読み込めます。
%dw 2.0 import myModule from modules::myModule output application/json --- myModule.someFunction(payload)
- Muleプロジェクト内で
src/main/resources/modules/myModule.dwl
のようなパスにモジュールを定義しておけばインポートできます。
関数のエイリアス
%dw 2.0 import upperCase as uc from dw::core::Strings output application/json --- uc("hello world")
- 公式モジュール
dw::core::Strings
などもよく活用します。
有名な組み込みモジュール例
dw::core::Strings
:文字列操作(upperCase
,lowerCase
,split
, etc.)dw::core::Dates
:日時操作(now()
,toString()
, etc.)dw::core::Numbers
:数値操作(round
,floor
,ceiling
, etc.)dw::core::Binaries
:バイナリデータ操作dw::core::Crypto
:暗号化ハッシュや署名
DataWeave 2.0でのよく使う式の実例
JSON -> JSONの変換例
入力(JSON)
{ "users": [ { "name": "Taro", "age": 20 }, { "name": "Hanako", "age": 25 } ], "admin": "Yamada" }
出力(JSON)に変換する例
%dw 2.0 output application/json --- { administrator: payload.admin, userCount: sizeOf(payload.users), userNames: payload.users map (u) -> u.name }
結果:
{ "administrator": "Yamada", "userCount": 2, "userNames": ["Taro", "Hanako"] }
JSON -> CSVの変換例
入力(JSON)
[ { "name": "Taro", "age": 20, "city": "Tokyo" }, { "name": "Hanako", "age": 25, "city": "Osaka" } ]
変換スクリプト
%dw 2.0 output text/csv quoteValues=false --- payload
結果(CSV):
name,age,city Taro,20,Tokyo Hanako,25,Osaka
XML -> JSONの変換例
入力(XML)
<departments> <department> <id>1</id> <name>Sales</name> </department> <department> <id>2</id> <name>Engineering</name> </department> </departments>
DataWeave
%dw 2.0 output application/json --- payload.departments.department map (dept) -> { departmentId: dept.id, departmentName: dept.name }
結果(JSON):
[ { "departmentId": "1", "departmentName": "Sales" }, { "departmentId": "2", "departmentName": "Engineering" } ]
名前空間 (Namespace) の扱い (主にXML)
XMLで名前空間がある場合、DataWeaveではキーに ns0::element
の形式を用います。必要に応じてHeaderでxmlns
を定義できます。
%dw 2.0 output application/json ns ns0 urn:example --- payload.ns0::Root.ns0::Child
変換フロー内でのattributesの利用
MuleのFlowでファイルを読み込んだ場合など、メッセージのメタデータはattributes
に格納されます。DataWeaveスクリプト内ではattributes
にアクセスしてヘッダ情報やファイル名などを参照できます。
%dw 2.0 output application/json --- { fileName: attributes.fileName, fileSize: attributes.fileSize, content: payload }
スクリプトのモジュール化・再利用
大規模プロジェクトでは、複数のDataWeaveスクリプトをモジュール化して整理すると管理が楽になります。
myModule.dwl
を作り、共通の関数を定義- 他のDataWeaveスクリプトで
import
して利用
関数型プログラミングの活用
DataWeaveは変数の再代入ができないため、副作用が少ない関数型スタイルでコードを整理できます。
- 無名関数を多用
- 変数に依存せず引数→戻り値のみでロジックを記述
ストリーミング
大容量データを扱う場合、DataWeaveはストリーミングモードでデータを逐次処理できます。<all>
に対応するような設定をすると、全件読み込まずに処理するなどの最適化が可能です(ただし処理内容によってはバッファリングが入るので要注意)。
ベストプラクティス
- マッピングの見やすさを優先
変換ロジックが可読性を保つように、mapObject
などを適切に使い、フラットに書きすぎない。 - 関数の分割・再利用
1つの巨大スクリプトにまとめるのではなく、意味ごとに関数を分割したり、別ファイルに切り出す。 - Null処理を明示的に
Nullを許容するか、default
値を設定するかを早期に決める。skipNullOn="everywhere"
などのオプションも活用。 - 型を意識する
特にCSVやXMLなどの入出力時は文字列になりやすいので、必要ならtoNumber()
等で型変換する。- 例:
payload.age as Number
- 例:
- サイズの大きいデータはストリーミングやchunkを検討
大量データを扱う場合、メモリやパフォーマンスに注意。DataWeaveのストリーミング機能を使い、可能な限り流し込み変換できるように工夫する。 - エラーハンドリングを考慮
変換処理中に異常データが来る場合、例外ハンドリングやtry
モジュールを組み合わせる。 - テスト可能性
MUnitなどのテスティングフレームワークを使ってDataWeaveスクリプトを単体テストする。関数型の構造を取るとテストしやすい。
このガイドでは、DataWeaveを扱うための基本概念から、構文、主要な関数、高度なモジュール活用例、ベストプラクティスまで幅広く紹介しました。DataWeaveはMuleSoftの強力なデータ変換エンジンであり、宣言的なスタイルと豊富なビルトイン関数を活用することで、複雑なデータマッピングを簡潔に表現できます。
実際の現場で扱うデータフォーマットは多岐にわたり、要件も多様です。しかしDataWeaveの表現力と拡張性を駆使すれば、JSON, XML, CSV, YAML, Javaオブジェクトなどの複数フォーマット間の変換を効率よく行えます。
ぜひ今回のガイドを参考にしながら、ご自身のプロジェクトでDataWeaveを活用し、実践的なスクリプトを書いてみてください。「書いて試す」ことが習熟への近道です。