【问题标题】:How can I specify an optional value in a tasks result selector?如何在任务结果选择器中指定可选值?
【发布时间】:2022-10-12 16:02:45
【问题描述】:

我想使用资源 arn:aws:states:::dynamodb:getItem 创建一个 dynamodb 步骤,其中某些属性可能不可用。

我的任务的相关部分如下:

"Get Config": {
  "Type": "Task",
  "Resource": "arn:aws:states:::dynamodb:getItem",
  "Next": "DummyPass",
  "Parameters": {
    "Key": {
      "pk": { "S.$": "$.someKey)" },
      "sk": { "S": "A" }
    },
    "TableName": "test_table"
  },
  "ResultPath": "$.config",
  "ResultSelector": {
    "foo.$": "$.Item.foo.S",
    "bar.$": "$.Item.bar.S"
  },
}

在此任务中,我尝试选择 DynamoDB 类型的注释项,并将其展平为仅包含键和值的 JSON 结构。

似乎没有任何可用的内在函数可以实现这一目标。

解决方法是创建一个 lambda,尽管它违背了现在由 step 函数支持的服务的目的。

【问题讨论】:

  • 我希望可以按照您的建议一步完成,我相信将来会更容易。在此之前,您可以通过Choice 步骤检查我们使用的模式,如以下答案所述:stackoverflow.com/a/73967219/179529
  • 谢谢@Guy,这些也是您回答中非常有效的观点。我的问题是我正在寻找一种方法来解析 GetItem 可能在某些字段不存在的情况下具有稀疏结果的结果。这意味着我什至无法在Pass 中执行此操作,因为无法指定可能不存在的字段。相反,我编写了一个 lambda,它进行解组并允许我指定应该包含的字段。

标签: amazon-web-services jsonpath aws-step-functions


【解决方案1】:

至于在结果选择器中指定一个可选值 - 这目前不能从 step 函数中获得。但是,您可以将整个输出传递到选择状态并基于该可选值进行条件。

为了尝试选择项目并将其展平为 JSON 结构,我们本身也不支持此功能,并且必须使用您提到的 lambda 函数作为解决方法。

【讨论】:

  • 谢谢 ehwang,我确实考虑过 Choice 方法,尽管我有一些我希望可用的属性,但它会变得多毛,虽然可能很聪明。我确实选择了一个简单的 JS lambda,它几乎暴露了 unmarshall,但添加了一个选项,允许调用者包含缺失的字段。当我完成测试时将其包含在此处。
【解决方案2】:

我通过创建一个暴露 jmespath 的 lambda 解决了这个问题,该 DataExpression 属性:

const jmespath = require("jmespath");

// convenience that ensures correct sync vs async lambda definition.
const { wrappedApply } = require("./lambda-tools.js");

function jmespathHandler (options) {
  return jmespath.search(options.Data, options.Expression);
}

module.exports = {
  jmespathHandler: wrappedApply(jmespathHandler)
};

给定以下输入:

{
  "x": {
    "foo": "FOO",
    "bar": "BAR",
  },
  "y": {
    "bat": "BAT"
  }
}

我现在可以使用如下定义调用此函数:

{
  "Type": "Task"
  "Resource": "arn:aws:states:::lambda:invoke",
  "End": true,
  "ResultSelector": {
    "FormatOutput.$": "$.Payload"
  },
  "OutputPath": "$.FormatOutput",
  "Parameters": {
    "FunctionName": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
    "Payload": {
      "Data.$": "States.JsonMerge($.x, $.y, false)",
      "Expression": "{Foo: foo, Bar: bar, Bat: bat, Baz: baz}"
    }
  },
}

现在将输出以下 json。

{
  "Foo": "FOO",
  "Bar": "BAR",
  "Bat": "BAT",
  "Baz": null
}

你可以在这里看到我已经重命名了键,但还包含了一个缺少的键Baz,因为 selected 将变为空。

请注意,我已经使用 States.JsonMerge 进行了演示,这可以直接在 jmespath 中实现,但是我只是使用它来演示您可能会发现有用的另一个工具。

为了完整起见,我在这里包括wrappedApply

function wrappedApply (action) {
  if (action.constructor.name === "AsyncFunction") {
    return action;
  }
  /* eslint consistent-return: "off" */
  return function (data, ctx, callback) {
    if (typeof callback !== "function") {
      return action(data, ctx, callback);
    }
    try {
      const res = action(data, ctx, callback);
      callback(null, res);
    } catch (e) {
      callback(e);
    }
  };
}

然后可以调用它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 2023-02-08
    • 2019-08-14
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多