Step Functions での JSONata を使用したデータの変換 - AWS Step Functions

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Step Functions での JSONata を使用したデータの変換

JSONata を使用すると、ワークフロー内のデータを選択して変換するための強力なオープンソースクエリと式言語が得られます。簡単な概要と JSONata の詳細なリファレンスについては、JSONata.org のドキュメントを参照してください。

次の動画では、DynamoDB の例を使用して Step Functions の変数と JSONata について説明します。

既存のワークフローで JSONata クエリ言語と変換言語を使用するには、オプトインする必要があります。コンソールでワークフローを作成するときは、最上位のステートマシン に JSONata を選択することをお勧めしますQueryLanguage。JSONPath を使用する既存または新規のワークフローの場合、コンソールには個々の状態を JSONata に変換するオプションがあります。

JSONata を選択すると、ワークフローフィールドは 5 つの JSONPath フィールド (InputPathParametersResultPath、、OutputPath) から ResultSelector2 つのフィールドのみに減らされます。 ArgumentsOutputです。また、JSON オブジェクトキー名.$には を使用しません

Step Functions を初めて使用する場合は、JSONata 式が次の構文を使用していることを知っておくだけで済みます。

JSONata 構文: "{% <JSONata expression> %}"

次のコードサンプルは、JSONPath から JSONata への変換を示しています。

# Original sample using JSONPath { "QueryLanguage": "JSONPath", // Set explicitly; could be set and inherited from top-level "Type": "Task", ... "Parameters": { "static": "Hello", "title.$": "$.title", "name.$": "$customerName", // With $customerName declared as a variable "not-evaluated": "$customerName" } }
# Sample after conversion to JSONata { "QueryLanguage": "JSONata", // Set explicitly; could be set and inherited from top-level "Type": "Task", ... "Arguments": { // JSONata states do not have Parameters "static": "Hello", "title": "{% $states.input.title %}", "name": "{% $customerName %}", // With $customerName declared as a variable "not-evaluated": "$customerName" } }

customerName に割り当てられた入力{ "title" : "Doctor" }と変数を指定すると"María"、両方のステートマシンは次の JSON 結果を生成します。

{ "static": "Hello", "title": "Doctor", "name": "María", "not-evaluated": "$customerName" }

次の図では、JSONPath (左) を JSONata (右) に変換するとステートマシンのステップの複雑さがどのように軽減されるかを示すグラフィカル表現を示しています。

JSONPath 状態と JSONata 状態のフィールドを比較する図。

(オプションで) 状態入力から引数にデータを選択して変換し、統合アクションに送信できます。JSONata では、 アクションから結果を選択して変換し、変数に割り当てたり、状態出力にしたりできます (オプション)。

注: 割り当てステップと出力ステップは並して行われます。変数の割り当て中にデータを変換することを選択した場合、その変換されたデータは出力ステップでは使用できません。出力ステップで JSONata 変換を再適用する必要があります。

JSONata クエリ言語を使用する状態の論理図。

QueryLanguage フィールド

ワークフロー ASL 定義には、ステートマシン定義の最上位レベルと個々の状態に QueryLanguageフィールドがあります。個々の状態QueryLanguage内に を設定することで、ステートマシンを一度にすべてアップグレードするのではなく、既存のステートマシンに JSONata を段階的に導入できます。

QueryLanguage フィールドは "JSONPath"または に設定できます"JSONata"。最上位QueryLanguageフィールドを省略すると、デフォルトで になります"JSONPath"。状態が状態レベルのQueryLanguageフィールドを含む場合、Step Functions はその状態に対して指定されたクエリ言語を使用します。状態に QueryLanguageフィールドが含まれていない場合、最上位QueryLanguageフィールドで指定されたクエリ言語が使用されます。

JSON 文字列での JSONata 式の記述

ASL フィールド、JSON オブジェクトフィールド、または JSON 配列要素の値の文字列が{% %}文字で囲まれている場合、その文字列は JSONata として評価されます。文字列は先頭にスペースを入れずに {%で始まり、末尾にスペースを入れずに %}で終わる必要があることに注意してください。式を不適切に開いたり閉じたりすると、検証エラーが発生します。

例:

  • "TimeoutSeconds" : "{% $timeout %}"

  • "Arguments" : {"field1" : "{% $name %}"} Task状態の

  • "Items": [1, "{% $two %}", 3] Map状態の

すべての ASL フィールドが JSONata を受け入れるわけではありません。例えば、各状態の Typeフィールドは定数文字列に設定する必要があります。同様に、Task状態の Resourceフィールドは定数文字列である必要があります。Map 状態Itemsフィールドは、JSON 配列または配列に評価する必要がある JSONata 式を受け入れます。

予約変数: $states

Step Functions は、 と呼ばれる単一の予約変数を定義します$states。JSONata 状態では、JSONata 式で使用できる$statesように、次の構造が に割り当てられます。

# Reserved $states variable in JSONata states $states = { "input": // Original input to the state "result": // API or sub-workflow's result (if successful) "errorOutput": // Error Output (only available in a Catch) "context": // Context object }

状態エントリでは、Step Functions は状態入力を に割り当てます$states.input。の値は$states.input、JSONata 式を受け入れるすべてのフィールドで使用できます。 $states.inputは常に元の状態入力を参照します。

TaskParallel、および Mapの状態の場合:

  • $states.result は、成功した場合の API またはサブワークフローの raw 結果を参照します。

  • $states.errorOutput は、API またはサブワークフローが失敗した場合のエラー出力を参照します。

    $states.errorOutput は、 Catch フィールドの Assignまたは で使用できますOutput

アクセスできない$states.errorOutputフィールドや状態で $states.resultまたは にアクセスしようとすると、ステートマシンの作成、更新、または検証時にキャッチされます。

$states.context オブジェクトは、、タスクトークンStartTime、初期ワークフロー入力など、特定の実行に関するワークフロー情報を提供します。詳細については、「Step Functions の Context オブジェクトから実行データにアクセスする 」を参照してください。

式エラーの処理

実行時に、JSONata 式の評価は次のようなさまざまな理由で失敗することがあります。

  • タイプエラー - $xや が数値でない場合、 などの式$yは失敗{% $x + $y %}します。

  • 型の非互換性 - 式は、フィールドが受け入れない型と評価される場合があります。たとえば、 フィールドには数値入力TimeoutSecondsが必要なため、 が文字列を$timeout返すと式{% $timeout %}は失敗します。

  • 範囲外の値 - フィールドの許容範囲外の値を生成する式は失敗します。例えば、 などの式{% $evaluatesToNegativeNumber %}TimeoutSecondsフィールドで失敗します。

  • 結果を返さない - JSON は未定義の値式を表すことができないため、式{% $data.thisFieldDoesNotExist %}はエラーになります。

いずれの場合も、インタープリタはエラー をスローしますStates.QueryEvaluationError。Task、Map、Parallel の状態では、エラーをキャッチするCatchフィールドと、エラーで再試行するRetryフィールドを指定できます。

JSONPath から JSONata への変換

以下のセクションでは、JSONPath と JSONata で記述されたコードの違いを比較して説明します。

パスフィールドが不要

ASL では、デベロッパーが のようにフィールドPathのバージョンを使用してTimeoutSecondsPath、JSONPath を使用するときに状態データから値を選択する必要があります。JSONata を使用すると、ASL は などの非パスPathフィールドで {% %}で囲まれた JSONata 式を自動的に解釈するため、フィールドを使用しなくなりますTimeoutSeconds

  • JSONPath レガシーの例: "TimeoutSecondsPath": "$timeout"

  • JSONata: "TimeoutSeconds": "{% $timeout %}"

同様に、 Map状態ItemsPathは、JSON 配列を受け入れる Itemsフィールド、または配列に評価する必要がある JSONata 式に置き換えられました。

JSON オブジェクト

ASL はペイロードテンプレートという用語を使用して、 Parametersおよび ResultSelectorフィールド値の JSONPath 式を含むことができる JSON オブジェクトを記述します。ASL は JSONata のペイロードテンプレートという用語を使用しません。JSONata の評価は、単独で行われるか、JSON オブジェクトまたは JSON 配列内で行われるかにかかわらず、すべての文字列に対して行われるためです。

.$ はもうありません

ASL では、JSONPath および組み込み関数を使用するには.$、ペイロードテンプレートのフィールド名に「」を追加する必要があります。を指定すると"QueryLanguage":"JSONata"、JSON オブジェクトフィールド名に.$「」規則を使用しなくなります。代わりに、JSONata 式を{% %}文字で囲みます。オブジェクトが他の配列またはオブジェクト内にどの程度深くネストされているかに関係なく、すべての文字列値フィールドに同じ規則を使用します。

引数と出力フィールド

QueryLanguage が に設定されている場合JSONata、古い I/O 処理フィールドは無効になり (InputPath、、ResultSelectorResultPathおよび OutputPathParameters、ほとんどの状態は Argumentsと の 2 つの新しいフィールドを取得しますOutput

JSONata では、JSONPath で使用されるフィールドと比較して、I/O 変換を簡単に実行できます。JSONata の機能により、 Argumentsは JSONPath で前の 5 つのフィールドよりも高性能Outputになります。これらの新しいフィールド名は、ASL を簡素化し、値を渡すモデルと返すモデルを明確にするのに役立ちます。

Arguments フィールドと Outputフィールド (および Map 状態の などの他の類似フィールドItemSelector) は、次のような JSON オブジェクトを受け入れます。

"Arguments": { "field1": 42, "field2": "{% jsonata expression %}" }

または、JSONata 式を直接使用することもできます。次に例を示します。

"Output": "{% jsonata expression %}"

出力は、、 など"Output":true、任意のタイプの JSON 値も受け入れることができます"Output":42

フィールドArgumentsOutputフィールドは JSONata のみをサポートするため、JSONPath を使用するワークフローでそれらを使用することは無効です。逆に、、InputPath、、ParametersResultSelector、、 などの JSONPath ResultPath OutputPath フィールドは JSONPath でのみサポートされるため、JSONata を最上位のワークフローまたは状態クエリ言語として使用する場合、パスベースのフィールドを使用することはできません。

パス状態

オプションの Result in a Pass 状態は、以前は仮想タスクの出力として扱われていました。ワークフローまたは状態クエリ言語として JSONata を選択すると、新しい出力フィールドを使用できるようになりました。

選択状態

JSONPath を使用する場合、Choice 状態には入力Variableと、次のような多数の比較パスがありますNumericLessThanEqualsPath

# JSONPath choice state sample, with Variable and comparison path "Check Price": { "Type": "Choice", "Default": "Pause", "Choices": [ { "Variable": "$.current_price.current_price", "NumericLessThanEqualsPath": "$.desired_price", "Next": "Send Notification" } ], }

JSONata では、Choice 状態には JSONata 式を使用できる Conditionがあります。

# Choice state after JSONata conversion "Check Price": { "Type": "Choice", "Default": "Pause" "Choices": [ { "Condition": "{% $current_price <= $states.input.desired_priced %}", "Next": "Send Notification" } ]

注: 変数と比較フィールドは JSONPath でのみ使用できます。条件は JSONata でのみ使用できます。

JSONata の例

次の例は、JSONata を試すために Workflow Studio で作成できます。ステートマシンを作成して実行することも、テストステートを使用してデータを渡し、ステートマシンの定義を変更することもできます。

例: 入力と出力

この例では、JSONata をオプトインするときに、 $states.inputを使用して状態入力と Outputフィールドを使用して状態出力を指定する方法を示します。

{ "Comment": "Input and Output example using JSONata", "QueryLanguage": "JSONata", "StartAt": "Basic Input and Output", "States": { "Basic Input and Output": { "QueryLanguage": "JSONata", "Type": "Succeed", "Output": { "lastName": "{% 'Last=>' & $states.input.customer.lastName %}", "orderValue": "{% $states.input.order.total %}" } } } }

ワークフローが入力として実行された場合:

{ "customer": { "firstName": "Martha", "lastName": "Rivera" }, "order": { "items": 7, "total": 27.91 } }

テストステートまたはステートマシンの実行は、次の JSON 出力を返します。

{ "lastName": "Last=>Rivera", "orderValue": 27.91 }
テスト中の状態の入出力を示すスクリーンショット。

例: JSONata によるフィルタリング

JSONata パス演算子を使用してデータをフィルタリングできます。例えば、入力用の製品のリストがあり、ゼロの kal を含む製品のみを処理するとします。次の ASL を使用してステートマシン定義を作成し、次のサンプル入力を使用してFilterDietProducts状態をテストできます。

JSONata でフィルタリングするためのステートマシン定義

{ "Comment": "Filter products using JSONata", "QueryLanguage": "JSONata", "StartAt": "FilterDietProducts", "States": { "FilterDietProducts": { "Type": "Pass", "Output": { "dietProducts": "{% $states.input.products[calories=0] %}" }, "End": true } } }

テスト用のサンプル入力

{ "products": [ { "calories": 140, "flavour": "Cola", "name": "Product-1" }, { "calories": 0, "flavour": "Cola", "name": "Product-2" }, { "calories": 160, "flavour": "Orange", "name": "Product-3" }, { "calories": 100, "flavour": "Orange", "name": "Product-4" }, { "calories": 0, "flavour": "Lime", "name": "Product-5" } ] }

ステートマシンでステップをテストした場合の出力

{ "dietProducts": [ { "calories": 0, "flavour": "Cola", "name": "Product-2" }, { "calories": 0, "flavour": "Lime", "name": "Product-5" } ] }
テスト対象の JSONata 式の出力例。

Step Functions によって提供される JSONata 関数

JSONata には、文字列、数値、集計、ブール値、配列、オブジェクト、日付/時刻、および高順序関数の関数ライブラリが含まれています。Step Functions には、JSONata 式で使用できる追加の JSONata 関数が用意されています。これらの組み込み関数は、Step Functions 組み込み関数の置き換えとして機能します。組み込み関数は、JSONPath クエリ言語を使用する状態でのみ使用できます。

注: パラメータとして整数値を必要とする組み込み JSONata 関数は、指定された整数以外の数値を自動的に切り捨てます。

$partition - 大きな配列をパーティション分割するためのStates.ArrayPartition組み込み関数に相当する JSONata。

最初のパラメータはパーティション化する配列で、2 番目のパラメータはチャンクサイズを表す整数です。戻り値は 2 次元配列になります。インタープリタは入力配列をチャンクサイズで指定されたサイズの複数の配列にチャンクします。配列に残っている項目の数がチャンクサイズよりも小さい場合、最後の配列チャンクの長さは前の配列チャンクの長さよりも短くなることがあります。

"Assign": { "arrayPartition": "{% $partition([1,2,3,4], $states.input.chunkSize) %}" }

$range - 値の配列を生成するStates.ArrayRange組み込み関数に相当する JSONata。

この関数は 3 つの引数を取ります。最初の引数は新しい配列の最初の要素を表す整数で、2 番目の引数は新しい配列の最後の要素を表す整数で、3 番目の引数は新しい配列の要素の差分値の整数です。戻り値は、関数の最初の引数から関数の 2 番目の引数までの範囲にある、新しく生成された値の配列で、その間に差分で調整された要素があります。差分値は正または負にすることができ、終了値に達するか超えるまで、各要素を最後の から増減します。

"Assign": { "arrayRange": "{% $range(0, 10, 2) %}" }

$hash - 特定の入力のハッシュ値を計算するためのStates.Hash組み込み関数に相当する JSONata。

この関数は 2 つの引数を取ります。最初の引数は、ハッシュされるソース文字列です。2 番目の引数は、ハッシュ計算のための へのハッシュアルゴリズムを表す文字列です。ハッシュアルゴリズムは、、"MD5""SHA-1"、、 "SHA-256" "SHA-384"のいずれかの値である必要があります"SHA-512"。戻り値は、データの計算されたハッシュの文字列です。

この関数は、JSONata がハッシュを計算する機能をネイティブにサポートしていないために作成されました。

"Assign": { "myHash": "{% $hash($states.input.content, $hashAlgorithmName) %}" }

$random - States.MathRandomで乱数 n を返す組み込み関数に相当する JSONata0 ≤ n < 1

関数は、ランダム関数のシード値を表すオプションの整数引数を取ります。この関数を同じシード値で使用すると、同じ数が返されます。

このオーバーロードされた関数は、組み込みの JSONata 関数$randomがシード値を受け入れないために作成されました。

"Assign": { "randNoSeed": "{% $random() %}", "randSeeded": "{% $random($states.input.seed) %}" }

$uuid - States.UUID組み込み関数の JSONata バージョン。

関数は引数を取りません。この関数は v4 UUID を返します。

この関数は、JSONata が UUIDs。

"Assign": { "uniqueId": "{% $uuid() %}" }

$parse - JSONata 文字列を逆シリアル化する JSONata 関数。

関数は、文字列化された JSON を唯一の引数として受け取ります。

JSONata $evalは を介してこの機能をサポートします$evalが、Step Functions ワークフローではサポートされていません。

"Assign": { "deserializedPayload": "{% $parse($states.input.json_string) %}" }