我希望将默认值传递给step函数
例如
"Parameters": {
"foo.$": "$.foo" OR "bar" if "$.foo" not specified
}
是否可以通过JSONPath本机执行此操作,还是必须使用选择+通过状态?
如果在输入中未指定参数时有不中断的方法,我什至会选择使用选择/传递。
如果我在输入中未包含"foo": ""
,则会收到类似"JSONPath ... could not be found in the input."
的错误
答案 0 :(得分:3)
我正在使用 Choice
和 Pass
状态的组合来解决这个问题。鉴于状态机至少获得一个空的输入对象,您可以使用 IsPresent
状态中的 Choice
比较运算符检查它是否存在成员。如果您的期望变量不存在,您可以路由到 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 Developer Guide, choice-state-example
答案 1 :(得分:1)
这可以通过在步函数开始时通过结合"Result"
和"ResultPath"
创建通过状态来实现。
"Result"
的通过状态将是foo
的值"ResultPath" : "$.foo"
处于通过状态,因此它将在您的通过输入中添加foo变量。相同的状态定义如下所示:
"Hello": {
"Type": "Pass",
"Result": "Added from Hello state",
"ResultPath":"$.foo",
"Next": "OtherStates"
}
一个例子是: 输入到Hello状态:
{
"bar" : "From input"
}
Hello状态输出:
{
"bar" : "From input",
"foo" : "Added from Hello state"
}
在这种情况下,它将为foo
添加值作为“从Hello状态添加”。因此,为避免由于输入中不存在foo
而导致事情中断,您将必须将此“通过状态”定义为要使用该状态的第一个状态或至少一个状态。
P.S。这适用于您仅需如上所述添加单个默认变量的情况。要添加多个默认变量,我建议创建一个Task State
并使用lambda函数实现创建默认变量。
答案 2 :(得分:1)
我们有一个类似的问题,该问题的解决方式可能会有所帮助,具体取决于您的SFN任务将要执行的操作。在我们的例子中是Lambda,因此我们可以处理其中的默认行为。
您可以将参数设置为“ $”值,该值将采用提供给SFN的所有输入。
"Parameters": {
"sfn_input.$": "$"
}
此“ sfn_input”参数现在将向舞台公开,并包含SFN的所有输入。在我们的情况下,我们可以在代码中处理其可选状态。
这显然仅在您的任务可以评估值的存在时才有效。甚至可能在SFN的开头添加了“初始化” Lambda的概念,以专门处理此问题,并添加传递回SFN的默认值。
答案 3 :(得分:0)
我能够通过创建一个cloudwatch规则来解决此问题,该规则每次运行stepfunction时都会插入json。
如果您转到Cloudwatch>创建规则>目标>步进功能>配置输入>常量(JSON文本)
您可以在其中插入默认的json,每次运行stepfunction时都会插入json。
答案 4 :(得分:0)
JSONPath只能查询您的JSON,并且您将无法即时添加数据,默认值将需要出现在输入中。经过多次测试后,我找不到执行此操作的“干净”方法,但这是实现此目的的一些方法。
方法1:
由于您提到过,即使输入中不存在参数,您甚至会想出一种不中断的方法,实际上这很容易做到,但是它不允许我们发送默认值(一个空数组)(如果缺少值)。为此,我们可以通过指定多个子项([''(,'')])来过滤叶节点上的特定值。例如,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
}
}
}
方法2:
取决于您对输入结构的控制程度,如果不需要从输入中引用任何其他变量,则可以使用InputPath和Parameters在单个状态下执行此操作。其背后的想法是将您的输入以以下形式输入州:
"OutputArray": [
{
"Bar": {
"Value": [
"Baz"
]
}
},
{
"Foo": {
"Value": [
"DefaultValueFoo"
]
}
}
]
数组的第一个元素应该是可能缺少的值,如果缺少该值,则默认值(foo)将是第一个元素。由于第一个元素将始终存在,因此我们可以使用JSONPath“ $ ['OutputArray'] [0] .. Value”获取第一个元素的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
}
}
}