AWS 步骤函数和可选参数

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."

的错误

我能够通过创建一个 cloudwatch 规则来解决这个问题,该规则在每次 stepfunction 运行时插入 json。

如果您转至 Cloudwatch > 创建规则 > 目标 > Stepfunction > 配置输入 > 常量(JSON 文本)

您可以在此处插入默认 json,每次运行 stepfunction 时都会插入 json。

这可以通过结合 "Result""ResultPath" 在步进函数的开始创建一个 Pass State 来实现。

    Pass State 的
  • "Result" 将是 foo
  • 的值
  • "ResultPath" : "$.foo" 处于 Pass 状态,因此它将在您的 pass 输入中添加 foo 变量。

相同的状态定义如下所示:

"Hello": {
      "Type": "Pass",
      "Result": "Added from Hello state",
      "ResultPath":"$.foo",
      "Next": "OtherStates"
    }

例如: 输入到你好状态:

{
 "bar" : "From input" 
}

Hello状态的输出:

{
 "bar" : "From input",
 "foo" : "Added from Hello state"
}

在这种情况下,它会将 foo 的值添加为 "Added from Hello state"。因此,为了避免因为输入中不存在 foo 而造成破坏,您必须将此通过状态定义为第一个状态或至少在您要使用它的状态之前。

P.S。这适用于您只需要添加您提到的单个默认变量的情况。要添加多个默认变量,我建议创建一个 Task State 并使用 lambda 函数实现创建默认变量。

JSONPath 只能查询您的 JSON,您将无法即时添加数据,您的输入中需要存在默认值。经过多次测试后,我找不到 "clean" 的方法,但这里有一些方法可以实现。

方法一:

既然你提到过如果输入中不存在参数,你甚至会找到一种不中断的方法,这实际上很容易做到,但是它不允许我们发送默认值 (空数组除外)如果缺少值。为此,我们可以通过指定多个子节点 (['' (, '')]) 来过滤掉叶节点上的特定值。例如 JSONPath "$.['Bar','Foo']" 将只过滤掉包含节点 Bar 和 Foo 的叶节点,但是它不会 return如果其中一个或两个都缺失,则出错。如果指定的所有子项都缺失,它将 return 一个空数组 []。这是一个示例状态机来说明这一点。

{
  "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" 来获取第一个元素的值。之后在 Parameters 中我们可以使用 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
    }
  }
}

我们有一个类似的问题,我们解决的方式可能会有所帮助,具体取决于您的 SFN 任务将执行的操作。在我们的例子中,它是一个 Lambda,因此我们可以处理其中的默认行为。

您可以将参数设置为“$”值,它将接受提供给 SFN 的所有输入。

"Parameters": {
      "sfn_input.$": "$"
}

这个“sfn_input”参数现在将暴露在舞台上并包含 SFN 的所有输入。在我们的例子中,我们可以处理它在代码中的可选存在。

这显然只有在您的任务可以评估值是否存在时才有效。甚至可以在 SFN 的开头添加“初始化”Lambda 的概念,以专门处理此问题并添加传递回 SFN 的默认值。

我正在使用 ChoicePass 状态的组合来解决这个问题。鉴于状态机至少获得一个空输入对象,您可以在 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"
    }
  }
}

有关更多信息,请参阅 AWS Step Functions 开发人员指南,选择状态示例