[英]AWS step functions and optional parameters
我想將參數的默認值傳遞給步進函數
例如,
"Parameters": {
"foo.$": "$.foo" OR "bar" if "$.foo" not specified
}
有沒有辦法使用 JSONPath 在本地執行此操作,還是我必須使用選擇 + 通過狀態?
如果在輸入中未指定參數時有辦法不中斷,我什至會選擇使用 choice/pass。
如果我不在輸入中包含"foo": ""
,我將收到類似"JSONPath... could not be found in the input."
的錯誤。
我正在使用Choice
和Pass
狀態的組合來解決這個問題。 鑒於狀態機至少獲得一個空輸入對象,您可以在Choice
狀態下使用IsPresent
比較運算符檢查它是否有成員存在。 如果您的願望變量不存在,您可以路由到Pass
狀態以注入默認回退對象。
{
"keyThatMightNotExist": {
"options": {
"foo": "bar",
"baz": false
},
"id": 1234
}
}
{
"Comment": "An example for how to deal with empty input and setting defaults.",
"StartAt": "Choice State: looking for input",
"States": {
"Choice State: looking for input": {
"Type": "Choice",
"Choices": [
{
檢查是否存在,如果存在,還要驗證子成員:
"And": [
{
"Variable": "$.keyThatMightNotExist",
"IsPresent": true
},
{
"Variable": "$.keyThatMightNotExist.id",
"IsNull": false
}
],
如果鍵變量存在且其子節點"id"
為true
,則跳過下一個狀態並跳到“與 $.keyThatMightNotExist 一起工作的狀態”
"Next": "State that works with $.keyThatMightNotExist"
}
],
"Default": "LoadDefaults"
},
以下是我們注入默認值的地方:
"LoadDefaults": {
"Type": "Pass",
"Result": {
"id": 0,
"text": "not applicable"
},
"ResultPath": "$.keyThatMightNotExist",
"Next": "State that works with $.keyThatMightNotExist"
},
此時,有一個對象可以使用。 來自實際輸入,或使用默認值:
"State that works with $.keyThatMightNotExist": {
"Type": "Succeed"
}
}
}
我們有一個類似的問題,我們解決的方式可能會有所幫助,具體取決於您的 SFN 任務將執行的操作。 在我們的例子中,它是一個 Lambda,因此我們可以處理其中的默認行為。
您可以將參數設置為“$”值,它將采用提供給 SFN 的所有輸入。
"Parameters": {
"sfn_input.$": "$"
}
這個“sfn_input”參數現在將暴露在舞台上並包含 SFN 的所有輸入。 在我們的例子中,我們可以處理它在代碼中的可選存在。
這顯然只有在您的任務可以評估價值的存在時才有效。 甚至可以在 SFN 的開頭添加“初始化”Lambda 的概念,以專門處理此問題並添加傳遞回 SFN 的默認值。
其實有一個更簡單的方法,它仍然使用額外的步驟; 但這比選擇+通過更好恕我直言。 這個概念是將您的默認值定義為Pass
狀態。 這是必需的,因為我們要將默認值與輸入合並。
我已經演示了您可以一次設置多個默認值,這揭示了不使用 Choice 的好處。
請注意,當我想引用被調用的參數時,我總是使用$$.Execution.Input
而不是依賴步進函數的輸入。 這讓我可以四處走動,而不用擔心另一個狀態會把它們消滅掉。
{
"Define Defaults": {
"Type": "Pass",
"Next": "Apply Defaults",
"ResultPath": "$.inputDefaults",
"Parameters": {
"foo": "bar",
"x": -1,
"baz": null
}
},
"Apply Defaults": {
"Type": "Pass",
"Next": "Start Work",
"ResultPath": "$.withDefaults",
"OutputPath": "$.withDefaults.args",
"Parameters": {
"args.$": "States.JsonMerge($.inputDefaults, $$.Execution.Input, false)"
}
}
}
這將為您提供一個產生的價值:
{
"foo": "bar",
"x": -1,
"baz": null
}
這可以通過結合"Result"
和"ResultPath"
在步驟函數的開始創建一個 Pass State 來實現。
"Result"
將是foo
的值"ResultPath": "$.foo"
in Pass State,因此它將在您的 pass 輸入中添加 foo 變量。同樣的狀態定義看起來像這樣:
"Hello": {
"Type": "Pass",
"Result": "Added from Hello state",
"ResultPath":"$.foo",
"Next": "OtherStates"
}
一個例子是:輸入到 Hello 狀態:
{
"bar" : "From input"
}
你好狀態的輸出:
{
"bar" : "From input",
"foo" : "Added from Hello state"
}
在這種情況下,它會將foo
的值添加為“從 Hello 狀態添加”。 因此,為了避免因為輸入中不存在foo
而造成破壞,您必須將此 Pass State 定義為第一個狀態或至少在您要使用它的狀態之前。
PS 這適用於您只需要添加您提到的單個默認變量的情況。 要添加多個默認變量,我建議創建一個Task State
並使用 lambda 函數實現創建默認變量。
我能夠通過創建一個 cloudwatch 規則來解決這個問題,該規則在每次 stepfunction 運行時插入 json。
如果您轉到 Cloudwatch > 創建規則 > 目標 > Stepfunction > 配置輸入 > 常量(JSON 文本)
您可以在那里插入默認的 json,每次運行 stepfunction 時都會插入 json。
JSONPath 只能查詢您的 JSON,您將無法即時添加數據,默認值需要出現在您的輸入中。 經過多次測試后,我無法找到一種“干凈”的方式來做到這一點,但這里有一些方法可以實現這一點。
方法一:
由於您提到過如果輸入中不存在參數,您甚至會選擇一種不中斷的方法,這實際上很容易做到,但是它不允許我們發送默認值(空數組除外) 如果缺少值。 為此,我們可以通過指定多個子節點 (['' (, '')]) 來過濾掉葉節點上的特定值。 例如,JSONPath "$.['Bar','Foo']" 將僅過濾掉包含節點 Bar 和 Foo 的葉節點,但是如果其中一個或兩個缺失,它不會返回錯誤。 如果指定的所有子項都缺失,它將返回一個空數組 []。 這是一個示例狀態機來說明這一點。
{
"StartAt": "ExampleLeafNodes",
"States": {
"ExampleLeafNodes": {
"Type": "Parallel",
"Branches": [
{
"StartAt": "State1-BarPresent",
"States": {
"State1-BarPresent": {
"Type": "Pass",
"Parameters": {
"Bar": "Baz"
},
"Next": "State2-BarPresent"
},
"State2-BarPresent": {
"Type": "Pass",
"Parameters": {
"Foo.$": "$.['Bar','AnyOtherField']"
},
"End": true
}
}
},
{
"StartAt": "State1-BarNotPresent",
"States": {
"State1-BarNotPresent": {
"Type": "Pass",
"Parameters": {
"Field1": "Value1"
},
"Next": "State2-BarNotPresent"
},
"State2-BarNotPresent": {
"Type": "Pass",
"Parameters": {
"Foo.$": "$.['Bar','AnyOtherField']"
},
"End": true
}
}
}
],
"End": true
}
}
}
方法二:
根據您對輸入結構的控制程度,如果您不需要從輸入中引用任何其他變量,您可以使用 InputPath 和參數在單個狀態中執行此操作。 這背后的想法是以以下形式將您的輸入輸入狀態:
"OutputArray": [
{
"Bar": {
"Value": [
"Baz"
]
}
},
{
"Foo": {
"Value": [
"DefaultValueFoo"
]
}
}
]
數組的第一個元素應該是可能缺失的值,如果該值缺失,則默認值 (foo) 將是第一個元素。 由於第一個元素始終存在,我們可以使用 JSONPath“$['OutputArray'][0]..Value” 來獲取第一個元素的值。 之后,在參數中,我們可以使用 JSONPath“$[0][0]”來提取確切的值。 這是此示例的示例狀態機:
{
"StartAt": "State1",
"States": {
"State1": {
"Type": "Pass",
"Parameters": {
"OutputArray": [
{
"Bar": {
"Value": [
"Baz"
]
}
},
{
"Foo": {
"Value": [
"DefaultValueFoo"
]
}
}
]
},
"Next": "State2"
},
"State2": {
"Type": "Pass",
"InputPath": "$['OutputArray'][0]..Value",
"Parameters": {
"Foo.$": "$[0][0]"
},
"End": true
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.