選取您的 Cookie 偏好設定

我們使用提供自身網站和服務所需的基本 Cookie 和類似工具。我們使用效能 Cookie 收集匿名統計資料,以便了解客戶如何使用我們的網站並進行改進。基本 Cookie 無法停用,但可以按一下「自訂」或「拒絕」以拒絕效能 Cookie。

如果您同意,AWS 與經核准的第三方也會使用 Cookie 提供實用的網站功能、記住您的偏好設定,並顯示相關內容,包括相關廣告。若要接受或拒絕所有非必要 Cookie,請按一下「接受」或「拒絕」。若要進行更詳細的選擇,請按一下「自訂」。

在 Step Functions 中使用 JSONata 轉換資料

焦點模式
在 Step Functions 中使用 JSONata 轉換資料 - AWS Step Functions

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 JSONata,您可以獲得強大的開放原始碼查詢和表達式語言,以選取轉換工作流程中的資料。如需簡介和完整的 JSONata 參考,請參閱 JSONata.org 文件。

下列影片說明具有 DynamoDB 範例之 Step Functions 中的變數和 JSONata:

您必須選擇加入,以使用現有工作流程的 JSONata 查詢和轉換語言。在 主控台中建立工作流程時,我們建議選擇 JSONata 作為最上層狀態機器 QueryLanguage。對於使用 JSONPath 的現有或新工作流程,主控台提供將個別狀態轉換為 JSONata 的選項。

選取 JSONata 後,您的工作流程欄位會從五個 JSONPath 欄位 (InputPathResultPath、 和 OutputPath) Parameters ResultSelector縮減為僅兩個欄位: 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" } }

指定的輸入{ "title" : "Doctor" }customerName指派給 的變數"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 狀態下,會將下列結構指派給 $states,以用於 JSONata 表達式:

# 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一律參考原始狀態輸入。

對於 TaskParallelMap 狀態:

  • $states.result 如果成功, 會參考 API 或子工作流程的原始結果。

  • $states.errorOutput 如果 API 或子工作流程失敗, 會參考錯誤輸出。

    $states.errorOutput 可用於 Catch 欄位的 AssignOutput

在建立、更新$states.result或驗證狀態機器時,將攔截無法存取存取 或 $states.errorOutput 的欄位和狀態。

$states.context 物件提供特定執行的工作流程資訊,例如 StartTime、任務字符和初始工作流程輸入。如需進一步了解,請參閱 從 Step Functions 中的內容物件存取執行資料

處理表達式錯誤

在執行時間,JSONata 表達式評估可能會因為各種原因而失敗,例如:

  • 類型錯誤 - 如果 $x$y不是數字{% $x + $y %},則 等表達式將會失敗。

  • 類型不相容 - 表達式可能會評估為 欄位不接受的類型。例如, 欄位TimeoutSeconds需要數值輸入,因此如果 $timeout傳回字串,則表示式{% $timeout %}會失敗。

  • 超出範圍的值 - 產生超出欄位可接受範圍的值的表達式將會失敗。例如, 等表達式{% $evaluatesToNegativeNumber %}會在 TimeoutSeconds 欄位中失敗。

  • 無法傳回結果 - JSON 無法代表未定義的值表達式,因此表達式{% $data.thisFieldDoesNotExist %}會導致錯誤。

在每個案例中,解譯器都會擲回錯誤:States.QueryEvaluationError。您的任務、映射和平行狀態可以提供擷取錯誤Catch的欄位,以及重試錯誤Retry的欄位。

從 JSONPath 轉換為 JSONata

下列各節會比較並說明以 JSONPath 和 JSONata 編寫的程式碼之間的差異。

沒有更多路徑欄位

ASL 要求開發人員使用 中的欄位Path版本TimeoutSecondsPath,以便在使用 JSONPath 時從狀態資料中選取值。當您使用 JSONata 時,您不再使用Path欄位,因為 ASL 會在非路徑欄位中自動為您解譯 {% %}封裝的 JSONata 表達式,例如 TimeoutSeconds

  • JSONPath 舊版範例: "TimeoutSecondsPath": "$timeout"

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

同樣地,Map狀態ItemsPath已取代為 欄位,該Items欄位接受 JSON 陣列或必須評估為陣列的 JSONata 表達式。

JSON 物件

ASL 使用 承載範本一詞來描述 JSON 物件,該物件可包含 ParametersResultSelector 欄位值的 JSONPath 表達式。ASL 不會使用 JSONata 的承載範本一詞,因為 JSONata 評估會針對所有字串進行,無論這些字串是發生在其本身,還是在 JSON 物件或 JSON 陣列內。

不再需要 .$

ASL 要求您將「.$」附加至承載範本中的欄位名稱,以使用 JSONPath 和內部函數。當您指定 時"QueryLanguage":"JSONata",您不再使用 JSON 物件欄位名稱的「.$」慣例。反之,您會以{% %}字元括住 JSONata 運算式。您為所有字串值欄位使用相同的慣例,無論物件巢狀在其他陣列或物件內的深度為何。

引數和輸出欄位

QueryLanguage 設定為 時JSONata,舊的 I/O 處理欄位將會停用 (InputPathResultSelectorResultPathOutputPath)Parameters,而且大多數狀態都會取得兩個新的欄位: ArgumentsOutput

相較於搭配 JSONPath 使用的欄位,JSONata 提供更簡單的 I/O 轉換執行方式。JSONata 的功能使用 JSONPath 讓 Arguments和 變得比前五個欄位Output更有能力。這些新的欄位名稱也有助於簡化您的 ASL,並釐清傳遞和傳回值的模型。

ArgumentsOutput 欄位 (以及其他類似欄位,例如Map狀態的 ItemSelector) 將接受 JSON 物件,例如:

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

或者,您可以直接使用 JSONata 表達式,例如:

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

輸出也可以接受任何類型的 JSON 值,例如:"Output":true"Output":42

ArgumentsOutput 欄位僅支援 JSONata,因此與使用 JSONPath 的工作流程搭配使用是無效的。相反地,InputPathParameters、、ResultSelectorResultPathOutputPath、 和其他 JSONPath 欄位僅支援 JSONPath,因此使用 JSONata 做為頂層工作流程或狀態查詢語言時,使用路徑型欄位無效。

通過狀態

處於通過狀態的選用結果先前視為虛擬任務的輸出。選取 JSONata 做為工作流程或狀態查詢語言時,您現在可以使用新的輸出欄位。

選擇狀態

使用 JSONPath 時,選擇狀態具有輸入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 時,選擇狀態具有 ,您可以在Condition其中使用 JSONata 表達式:

# 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 範例

下列範例可在 Workflow Studio 中建立,以實驗 JSONata。您可以建立和執行狀態機器,或使用測試狀態來傳入資料,甚至修改狀態機器定義。

範例:輸入和輸出

此範例顯示當您選擇加入 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 路徑運算子來篩選資料。例如,假設您有一個產品清單可供輸入,而且您只想要處理包含零卡的產品。您可以使用下列 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 - JSONata 等同於States.ArrayPartition內部 函數以分割大型陣列。

第一個參數是要分割的陣列,第二個參數是代表區塊大小的整數。傳回值將是二維陣列。解譯器會將輸入陣列區塊化為區塊大小所指定大小的多個陣列。如果陣列中剩餘項目的數量小於區塊大小,則最後一個陣列區塊的長度可能會小於先前陣列區塊的長度。

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

$range - JSONata 等同於States.ArrayRange內部函數以產生值陣列。

此函數需要三個引數。第一個引數是代表新陣列第一個元素的整數,第二個引數是代表新陣列最終元素的整數,第三個引數是新陣列中元素的變動值整數。傳回值是新產生的值陣列,範圍從函數的第一個引數到函數的第二個引數,其中元素介於 之間,並由 delta 調整。差異值可以是正值或負值,這會從最後一個遞增或遞減每個元素,直到達到或超過結束值為止。

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

$hash - JSONata 等同於States.Hash內部函數,用於計算指定輸入的雜湊值。

此函數需要兩個引數。第一個引數是要雜湊的來源字串。第二個引數是代表雜湊演算法的字串,用於雜湊計算。雜湊演算法必須是下列其中一個值:"MD5""SHA-1""SHA-256""SHA-384""SHA-512"。傳回值是計算資料雜湊的字串。

建立此函數是因為 JSONata 原生不支援計算雜湊的能力。

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

$random - JSONata 等同於States.MathRandom內部函數,以傳回隨機數字 n,其中 0 ≤ n < 1

函數會採用選擇性整數引數,代表隨機函數的種子值。如果您使用此函數搭配相同的種子值,則會傳回相同的數字。

建立此過載函數是因為內建 JSONata 函數$random不接受種子值。

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

$uuid - JSONata 版States.UUID的內部函數。

函數不會使用引數。此函數會傳回 v4 UUID。

建立此函數是因為 JSONata 原生不支援產生 UUIDs的能力。

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

$parse - JSONata 函數可還原序列化 JSON 字串。

函數會採用字串化 JSON 做為其唯一引數。

JSONata 透過 支援此功能$eval;但 Step Functions 工作流程$eval不支援 。

"Assign": { "deserializedPayload": "{% $parse($states.input.json_string) %}" }
隱私權網站條款Cookie 偏好設定
© 2025, Amazon Web Services, Inc.或其附屬公司。保留所有權利。