本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 JSONata,您可以獲得強大的開放原始碼查詢和表達式語言,以選取和轉換工作流程中的資料。如需簡介和完整的 JSONata 參考,請參閱 JSONata.org 文件。
下列影片說明具有 DynamoDB 範例之 Step Functions 中的變數和 JSONata:
您必須選擇加入,以使用現有工作流程的 JSONata 查詢和轉換語言。在 主控台中建立工作流程時,我們建議選擇 JSONata 作為最上層狀態機器 QueryLanguage
。對於使用 JSONPath 的現有或新工作流程,主控台提供將個別狀態轉換為 JSONata 的選項。
選取 JSONata 後,您的工作流程欄位會從五個 JSONPath 欄位 (InputPath
、ResultPath
、 和 OutputPath
) Parameters
ResultSelector
縮減為僅兩個欄位: Arguments
和 Output
。此外,您不會.$
在 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 (右) 將如何降低狀態機器中步驟的複雜性:

您可以 (選用) 從狀態輸入選取資料並將其轉換為引數,以傳送至整合動作。然後,您可以使用 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
一律參考原始狀態輸入。
對於 Task
、 Parallel
和 Map
狀態:
-
$states.result
如果成功, 會參考 API 或子工作流程的原始結果。 -
$states.errorOutput
如果 API 或子工作流程失敗, 會參考錯誤輸出。$states.errorOutput
可用於Catch
欄位的Assign
或Output
。
在建立、更新$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 物件,該物件可包含 Parameters
和 ResultSelector
欄位值的 JSONPath 表達式。ASL 不會使用 JSONata 的承載範本一詞,因為 JSONata 評估會針對所有字串進行,無論這些字串是發生在其本身,還是在 JSON 物件或 JSON 陣列內。
不再需要 .$
ASL 要求您將「.$
」附加至承載範本中的欄位名稱,以使用 JSONPath 和內部函數。當您指定 時"QueryLanguage":"JSONata"
,您不再使用 JSON 物件欄位名稱的「.$
」慣例。反之,您會以{% %}
字元括住 JSONata 運算式。您為所有字串值欄位使用相同的慣例,無論物件巢狀在其他陣列或物件內的深度為何。
引數和輸出欄位
當 QueryLanguage
設定為 時JSONata
,舊的 I/O 處理欄位將會停用 (InputPath
、ResultSelector
、 ResultPath
和 OutputPath
)Parameters
,而且大多數狀態都會取得兩個新的欄位: Arguments
和 Output
。
相較於搭配 JSONPath 使用的欄位,JSONata 提供更簡單的 I/O 轉換執行方式。JSONata 的功能使用 JSONPath 讓 Arguments
和 變得比前五個欄位Output
更有能力。這些新的欄位名稱也有助於簡化您的 ASL,並釐清傳遞和傳回值的模型。
Arguments
和 Output
欄位 (以及其他類似欄位,例如Map
狀態的 ItemSelector
) 將接受 JSON 物件,例如:
"Arguments": {
"field1": 42,
"field2": "{% jsonata expression %}"
}
或者,您可以直接使用 JSONata 表達式,例如:
"Output": "{% jsonata expression %}"
輸出也可以接受任何類型的 JSON 值,例如:"Output":true
、"Output":42
。
Arguments
和 Output
欄位僅支援 JSONata,因此與使用 JSONPath 的工作流程搭配使用是無效的。相反地,InputPath
、Parameters
、、ResultSelector
ResultPath
OutputPath
、 和其他 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 路徑運算子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"
}
]
}

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) %}"
}