コンテンツパラメータ

次の操作 (疑似コード) を考えてみます。

<file:write path="hello.txt" overwrite="true" content="#[payload]" />

操作を構成するパラメータは、多くの場合異なる役割を果たします。

動作パラメータ

これらのパラメータは、操作の動作方法を決定する設定を管理します。上記の例では、overwrite パラメータは、ファイルがすでに存在する場合に実行するアクションを設定します。path パラメータは、コンテンツの書き込み先を示します。両方のパラメータは操作を構成しますが、これは Write 操作であるため、 書き込まれるデータの主な概念を表すものではありません。

一部の操作は、次のように動作パラメータによって排他的に形成されます。

<file:copy from="somePath" to="anotherPath" />

この操作はコンテンツを取得しないため、両方のパラメータが動作パラメータです。コンテンツはコピーされるファイル内にあります。

コンテンツパラメータ

上記の動作パラメータの説明を考慮すると、コンテンツパラメータの定義は明確です。上記の file:write の例では、コンテンツは @Content パラメータです。

コンテンツパラメータには、次の特性があります。

  • 式を受け入れる必要がある。SUPPORTS_EXPRESSIONS と EXPRESSION_REQUIRED の両方がサポートされていますが、@Expression(NOT_SUPPORTED) が使用されている場合はコンパイルに失敗します。

  • 各コンテンツパラメータは、コンテンツを生成するために独自の DataWeave スクリプトを埋め込むことができる。

  • コンテンツパラメータは、埋め込まれた DataWeave スクリプトを有効にするため、常にテキスト要素として DSL に変換される。

今回はコンテンツパラメータを使用して、もう一度 file:write 操作を考えてみます。この操作をフローで使用し、メッセージペイロードは XML として保存する JSON であるとします。

<file:write path="myFile.xml">
	<file:content>
		<![CDATA[#[
        %dw 2.0
        output application/xml
        ---
        rootElement: payload
        ]
        ]]>
	</file:content>
</file:write>

モジュールのコードでは、content パラメータは @Content アノテーションでマークされます。

public void write(String path, @Content InputStream content) {
    // write code
}

プライマリコンテンツパラメータ

場合によっては、次のように操作に多数のコンテンツパラメータがあります。

<http:request path="/my/api">
	<http:request-builder>
		<http:body>
			#[body..]
		</http:body>
		<http:uri-params>
			#[uri-params …]
		</http:uri-params>
		<http:headers>
			#[you get the picture..]
		</http:headers>
	</http:request-builder>
</http:request>

ご覧のとおり、必要なだけのコンテンツパラメータを設定できます。つまり、@Content アノテーションを複数のメソッド引数で使用できます。 ただし、その場合でも body パラメータは他のパラメータよりも重要です。ヘッダーも HTTP 要求で送信されるコンテンツの一部ですが、それらのヘッダーは送信される本文を補完するものです。そのため、操作に複数のコンテンツパラメータがある場合、@Content(primary = true) を使用してその 1 つをプライマリコンテンツとしてマークする必要があります。

プライマリコンテンツパラメータは、通常のコンテンツパラメータと同じ特性のすべてに加えて、次の特性があります。

  • 自動的に省略可能になる。

  • デフォルトで自動的に #[payload] に設定される。

これら 2 つの機能は、ランタイムによって自動的にパラメータに追加されます。

コンテンツパラメータが 1 つのみだった file:write の例に戻りましょう。これはプライマリですか? はい。操作のコンテンツパラメータが 1 つのみの場合、SDK は自動的にそれをプライマリと見なします。つまり、file:write 操作のコンテンツパラメータは自動的に省略可能になり、デフォルトで #[payload] に設定されます。これは、モジュール間の一貫性を強化するために役立ちます。

プライマリコンテンツのデフォルトの変更

プライマリコンテンツをデフォルトでペイロード以外の何かに設定する必要がある極端な状況があります。これは、操作のコンテンツパラメータが 1 つのみで、そのパラメータが常に必要とは限らない場合に発生しがちです。たとえば、データコネクタを考えてみます。選択クエリの入力パラメータはプライマリコンテンツですが、すべてのクエリに入力パラメータが必要なわけではありません。そのため、実際のデフォルトは空のマップにする必要があります。

これを行うには、@Content アノテーションと @Optional アノテーションを組み合わせます。たとえば、次の例はデフォルトを空のマップに設定しています。

public List<Map> select(@Text String sql,
                        @Optional(defaultValue="#[{}]") @Content Map<String, Object> inputParameters) {
	// select
}

コンテンツパラメータを省略可能として、デフォルトなしで設定することもできます。

public List<Map> select(@Text String sql,
                        @Optional @Content Map<String, Object> inputParameters) {
	// select
}

最後に、次のように @Content アノテーションを @NullSafe と組み合わせることができます。

public List<Map> select(@Text String sql,
                        @Optional @NullSafe @Content Map<String, Object> inputParameters) {
	// select
}
最初と 3 番目の例は同等です。ただし、モジュールのユーザの操作性が向上するため、@NullSafe オプションをお勧めします。#[{}] を明示的なデフォルトとして設定すると、経験の浅い Mule ユーザは混乱する可能性があります。

パラメータグループへのコンテンツパラメータの埋め込み

上記の http:request 操作のコンテンツパラメータは、request-builder という要素に含まれています。使いやすさの理由から、コネクタの作成者はすべての要求関連の属性をそれを囲むオブジェクトでグループ化することを選択しました。これは、SDK によって 次の方法でサポートされています。

public void request(String path, @ParameterGroup(showInDsl=true) HttpRequestBuilder requestBuilder) {
    // request
}

ご覧のとおり、ここにはコンテンツパラメータはありません。ただし、HttpRequestBuilder クラス内を見ると、@Content アノテーションがあります。

public class HttpRequestBuilder {

    @Parameter
    @Content(primary = true)
    private InputStream body;

    @Parameter
    @Content
    @NullSafe
    private Map<String, String> uriParams;

    @Parameter
    @Content
    @NullSafe
    private Map<String, String> uriParams;
}
サンプル要求操作の HttpRequestBuilder 引数から @ParameterGroup アノテーションを削除すると、コンパイルエラーになります。@Content は複合型には使用できません。

Was this article helpful?

💙 Thanks for your feedback!

Edit on GitHub