本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用變數和 JSONata 管理狀態
Step Functions 最近新增了變數和 JSONata 來管理狀態和轉換資料。
在部落格文章中進一步了解 使用 中的變數和 JSONata 簡化開發人員體驗 AWS Step Functions
下列影片說明具有 DynamoDB 範例之 Step Functions 中的變數和 JSONata:
透過變數和狀態輸出,您可以在工作流程的步驟之間傳遞資料。
使用工作流程變數,您可以在步驟中存放資料,並在未來的步驟中擷取該資料。例如,您可以存放 API 回應,其中包含稍後可能需要的資料。相反地,狀態輸出只能用作下一個步驟的輸入。
變數的概念概觀
使用工作流程變數,您可以存放資料以供稍後參考。例如,步驟 1 可能會存放 API 請求的結果,因此可在步驟 5 稍後重複使用部分請求。
在下列情況下,狀態機器會從 API 擷取資料一次。在步驟 1 中,工作流程會將傳回的 API 資料 (每個狀態最多 256 KiB) 存放在變數「x」中,以供後續步驟使用。
如果沒有變數,您需要將資料從步驟 1 傳遞到步驟 2 再傳遞到步驟 3 再傳遞到步驟 4,才能在步驟 5 中使用。如果這些中繼步驟不需要資料,該怎麼辦? 透過輸出和輸入將資料從狀態傳遞到狀態,是不必要的努力。
透過 變數,您可以存放資料,並在任何未來的步驟中使用。您也可以修改、重新排列或新增步驟,而不會中斷資料的流程。由於變數的彈性,您可能只需要使用輸出來傳回平行和映射子工作流程的資料,並在狀態機器執行結束時傳回資料。
支援變數的狀態
下列狀態類型支援Assign
宣告和指派值給變數:Pass、Task、Map、Parallel、Choice、Wicket。
若要設定變數,請為 JSON 物件提供變數名稱和值:
"Assign": {
"productName": "product1",
"count" : 42,
"available" : true
}
若要參考變數,請在名稱前面加上美元符號 ($
),例如 $productName
。
預留變數 :$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 中的內容物件存取執行資料 。
變數名稱語法
變數名稱遵循 Unicode® 標準附件 #31 中所述的 Unicode
變數名稱慣例類似於 JavaScript 和其他程式設計語言的規則。
變數範圍
Step Functions 工作流程使用工作流程本機範圍來避免具有變數的競爭條件。
Workflow-local 範圍包含狀態機器狀態欄位內的所有狀態,但不包括平行或映射狀態內的狀態。Parallel 或 Map 狀態內的狀態可以參考外部範圍變數,但它們會建立和維護自己的個別工作流程本機變數和值。
Parallel
分支和Map
反覆運算可以從外部範圍存取變數值,但它們無法存取其他並行分支或反覆運算的變數值。處理錯誤時, 中的 Assign
欄位Catch
可以將值指派給外部範圍中的變數,也就是存在平行/映射狀態的範圍。
例外狀況:分散式映射狀態目前無法參考外部範圍內的變數。
如果範圍內的任何狀態為其指派值,則範圍內存在變數。為了協助避免常見錯誤,內部範圍內指派的變數不能具有與外部範圍內指派的變數相同的名稱。例如,如果頂層範圍將值指派給名為 的變數myVariable
,則其他範圍 (在 內Map
,Parallel
) myVariable
也無法指派給 。
對變數的存取取決於目前的範圍。平行和映射狀態有自己的範圍,但可以存取外部範圍中的變數。
當平行或映射狀態完成時,其所有變數都會超出範圍並停止存取。使用輸出欄位將資料從平行分支和映射反覆運算中傳遞出。
ASL 中的指派欄位
ASL 中的 Assign
欄位用於將值指派給一或多個變數。Assign
欄位可在每個狀態的頂層 ( Succeed
和 除外Fail
)、Choice
狀態內規則和Catch
欄位內使用。例如:
# Example of Assign with JSONata
"Store inputs": {
"Type": "Pass",
"Next": "Get Current Price",
"Comment": "Store the input desired price into a variable: $desiredPrice",
"Assign": {
"desiredPrice": "{% $states.input.desired_price %}",
"maximumWait": "{% $states.input.max_days %}"
}
},
Assign
欄位接受 JSON 物件。每個最上層欄位都會命名要指派的變數。在上述範例中,變數名稱為 desiredPrice
和 maximumWait
。使用 JSONata 時, {% ... %}
表示 JSONata 表達式,其中可能包含變數或更複雜的表達式。如需 JSONata 表達式的詳細資訊,請參閱 JSONata.org 文件。
使用 JSONata 做為查詢語言時,下圖顯示如何平行處理指派和輸出欄位。請注意含義:指派變數值不會影響狀態輸出。
下列 JSONata 範例order.product
會從狀態輸入擷取。變數currentPrice
會設定為任務結果的值。
# Example of Task with JSONata assignment from result
{
"Type": "Task",
...
"Assign": {
"product": "{% $states.input.order.product %}",
"currentPrice": "{% $states.result.Payload.current_price %}"
},
"Next": "the next state"
}
注意:您無法將值指派給變數的一部分。例如,您可以 "Assign":{"x":42}
,但無法 "Assign":{"x.y":42}
或 "Assign":{"x[2]":42}
。
指派欄位中的評估順序
Step Functions 狀態中的所有變數參考都會使用與狀態項目相同的值。
先前的事實對於了解 Assign
欄位如何將值指派給一或多個變數非常重要。首先,計算新值,然後 Step Functions 將新值指派給變數。新的變數值將從下一個狀態開始提供。例如,請考慮下列Assign
欄位:
# Starting values: $x=3, $a=6
"Assign": {
"x": "{% $a %}",
"nextX": "{% $x %}"
}
# Ending values: $x=6, $nextX=3
在上述範例中,x
會同時指派和參考變數。
請記住,系統會先評估所有表達式,然後進行指派。而新指派的值將在下一個狀態提供。
讓我們詳細了解範例。假設在先前的狀態中, $x
被指派了三 (3) 個值, $a
被指派了六 (6) 個值。下列步驟說明此程序:
-
系統會使用所有變數的目前值來評估所有表達式。
表達式
"{% $a %}"
將評估為 6,"{% $x %}"
並將評估為 3。 -
接下來,會進行指派:
$x
將獲指派值六 (6)$nextX
將指派三 (3) 個
注意:如果先前$x
未指派 ,則範例會失敗,因為 $x
會未定義。
總而言之,Step Functions 會評估所有表達式,然後進行指派。變數在 Assign
欄位中發生的順序並不重要。
限制
標準和快速工作流程的單一變數大小上限為 256Kib。
單一Assign
欄位中所有變數的合併大小上限也是 256Kib。例如,您可以將 X 和 Y 指派給 128KiB,但無法在相同欄位中同時將 X 和 Y 指派給 256KiBAssign
。
所有儲存變數的總大小每次執行不得超過 10MiB。
在 JSONPath 狀態中使用變數
變數也可用於使用 JSONPath 查詢語言的狀態。
您可以在任何接受 JSONpath 表達式 ( $.
或 $$.
語法) 的欄位中參考變數,但 除外ResultPath
,其會指定狀態輸入中的位置以注入狀態的結果。變數無法在 中使用ResultPath
。
在 JSONPath 中, $
符號是指「目前」值,並$$
代表狀態內容物件。JSONPath 表達式的開頭可以是 ,$.
如 所示$.customer.name
。您可以使用 存取內容$$.
,如 所示$$.Execution.Id
。
若要參考變數,您也可以在變數名稱之前使用 $
符號,例如 $x
或 $order.numItems
。
在接受內部函數的 JSONPath 欄位中,變數可用於引數,例如 States.Format('The order number is {}', $order.number)
。
下列圖表說明 JSONPath 任務中的指派步驟與 ResultSelector 同時在 中發生的方式:
在 JSONPath 中指派變數
JSONPath 變數指派的行為類似於承載範本。結尾為 的欄位.$
表示值是 JSONPath 表達式,Step Functions 會在狀態機器執行期間評估為 值 (例如: $.order..product
和 $.order.total
)。
# Example of Assign with JSONPath
{
"Type": "Task",
...
"Assign": {
"products.$": "$.order..product",
"orderTotal.$": "$.order.total"
},
"Next": "the next state"
}
對於 JSONPath 狀態, $
Assign
欄位中的 值取決於狀態類型。在 Task,
Map
中, Parallel
狀態$
是指 API/子工作流程結果。在 Choice
和 Wait
狀態中, $
是指有效輸入,也就是 之後的值InputPath
已套用至狀態輸入。對於 Pass
, $
是指結果,無論是由 Result
欄位還是 InputPath
/Parameters
欄位產生。
下列 JSONPath 範例會將 JSON 物件指派給 details
變數、JSONPath 表達式的結果$.result.code
指派給 resultCode
,以及 JSONPath 表達式的結果States.Format('Hello {}', $customer.name)
指派給 message
。如果處於 Task
狀態,則 $
中的 $.order.items
和 $.result.code
會參考 API 結果。系統會使用內容物件 中的值來指派startTime
變數$$.Execution.StartTime
。
"Assign": {
"details": {
"status": "SUCCESS",
"lineItems.$": "$.order.items"
},
"resultCode.$": "$.result.code",
"message.$": "States.Format('Hello {}', $customer.name)",
"startTime.$": "$$.Execution.StartTime"
}