简体   繁体   English

为什么我的任务的 JSON output 被 AWS Step Functions 转义?

[英]Why is the JSON output of my task being escaped by AWS Step Functions?

I have a Lambda function that runs in a step function.我有一个 Lambda function 在步骤 function 中运行。

The Lambda function returns a JSON string as output. Lambda function 返回 JSON 字符串作为 output。

When I debug the function locally, I see that the JSON is valid but when I run the step function and get to the next step after my function, I can see that all my " have turned to \" and there is a " at the beginning and end of my JSON.当我在本地调试 function 时,我看到 JSON 是有效的,但是当我运行步骤 function 并在我的 function 之后进入下一步时,我可以看到我所有的"已经转向\"并且有一个"在我的 JSON 的开始和结束。

So a JSON object that looks like the following when I debug my function:所以当我调试我的 function 时,一个 JSON object 看起来像下面这样:

{"test":60,"test2":"30000","test3":"result1"}

Ends up looking like the following as the input of the step after my lambda:在我的 lambda 之后的步骤输入最终看起来像下面这样:

"{\"test\":60,\"test2\":\"30000\",\"test3\":\"result1\"}"

Why does my valid JSON object end up being escaped?为什么我有效的 JSON object 最终被转义了?

How can I prevent this from happening?我怎样才能防止这种情况发生?

The Lambda function returns a JSON string as output. Lambda 函数返回一个 JSON 字符串作为输出。

That is exactly why your JSON is being escaped - you're returning your object as a JSON string eg using JSON.stringify not as a JSON object .正是您的 JSON 被转义的原因 - 您将对象作为 JSON字符串返回,例如使用JSON.stringify而不是 JSON object

The easiest way to fix this would be to just return the object & not convert the output to a JSON string.解决此问题的最简单方法是仅返回对象而不将输出转换为 JSON 字符串。 That way, it won't not be escaped & will be returned, as you expect, as an object.这样,它就不会被转义,并且会像您期望的那样作为对象返回。

However, if it must stay as a JSON string for whatever reason, you can use the States.StringToJson(...) intrinsic function to unescape the escaped JSON string using the ResultSelector property of your task.但是,如果由于某种原因它必须保留为 JSON 字符串,您可以使用States.StringToJson(...) 内部函数来使用任务的ResultSelector属性对转义的 JSON 字符串进行转义。


So for example, if your output is:例如,如果您的输出是:

{
    "Payload": "{\"test\":60,\"test2\":\"30000\",\"test3\":\"result1\"}",
    ...
}

To be able to unescape the output before passing it to the next task, set the ResultSelector of your task to:为了能够在将输出传递给下一个任务之前取消转义输出,请将任务的ResultSelector设置为:

"ResultSelector": {
    "Payload.$":"States.StringToJson($.Payload)"
}

Or if using the Workflow Studio, click on the task, check the Output > Transform result with ResultSelector - optional checkbox and fill in the text box with the above ResultSelector object:或者,如果使用 Workflow Studio,单击任务,选中Output > Transform result with ResultSelector - optional复选框,并使用上述ResultSelector对象填充文本框:

在此处输入图片说明


Either way, the final result of your task definition should look like this:无论哪种方式,您的任务定义的最终结果都应如下所示:

{
  ...
  "States": {
    "Lambda Invoke": {
      "Type": "Task",
      ...
      "ResultSelector": {
        "Payload.$":"States.StringToJson($.Payload)"
      }
    }
  }
}

The output will then be as you expect:然后输出将如您所料:

{
  "Payload": {
    "test": 60,
    "test2": "30000",
    "test3": "result1"
  }
}

在此处输入图片说明

While the answer from @Ermiya Eskandary is entirely correct, you also have a few more options that you can use to your advantage with or without using ResultSelector (if its a stringified json, then you pretty much have to use ResultSelector however as that answer mentioned) property.虽然@Ermiya Eskandary 的答案是完全正确的,但您还有更多选项可以在使用或不使用 ResultSelector 的情况下发挥自己的优势(如果它是字符串化的 json,那么您几乎必须使用 ResultSelector 但是正如该答案所提到的) 财产。 ResultPath and OutputPath.结果路径和输出路径。

If you do not need the incoming event for anything else after this Lambda, then have your lambda return an Json like object (ie: if in python, return a dict)如果在此 Lambda 之后您不需要任何其他事件的传入事件,那么让您的 lambda 返回一个类似 Json 的对象(即:如果在 python 中,返回一个字典)

In your State Machine Definition, then include two properties in your Lambda Task在您的状态机定义中,然后在您的 Lambda 任务中包含两个属性

OutputPath:"$.SomeKey",
ResultPath:"$.SomeKey"

the SomeKey has to be the same for both.两者的 SomeKey 必须相同。

What these two lines together in the task properties is say (ResultPath) "Put the output of this lambda in the event under the key 'SomeKey'" and then (OutputPath) "only send this key on to the next Task"这两行在任务属性中的意思是 (ResultPath) “将此 lambda 的输出放在键 'SomeKey' 下的事件中”,然后 (OutputPath) “仅将此键发送到下一个任务”

If you still need the data from the Input, you can use ResultPath: alone, which will put the output of the Lambda under the key assigned and append it to the InputEvent as well.如果您仍然需要来自 Input 的数据,您可以单独使用ResultPath:它将 Lambda 的输出放在指定的键下并将其附加到 InputEvent。

See This documentation for more info 有关更多信息,请参阅此文档

Newbie to step functions here.新手在这里执行功能。 I noticed there are two different ways to call a lambda from step functions:我注意到有两种不同的方法可以从步骤函数中调用 lambda:

The AWS-SDK way using Resource: arn:aws:states:::aws-sdk:lambda:invoke AWS-SDK 使用Resource: arn:aws:states:::aws-sdk:lambda:invoke

The "optimised" way using Resource: arn:aws:states:::lambda:invoke使用Resource: arn:aws:states:::lambda:invoke

I found that the optimized way does a much better job with the JSON coming back from the python Lambda whereas the AWS SDK way was an escaped mess.我发现优化的方式在 JSON 从 python Lambda 返回时做得更好,而 AWS SDK 方式是逃脱的混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS Step Functions:将任务输入与 *部分* 任务输出相结合 - AWS Step Functions: Combine task input with *partial* task output 如何使用 AWS Step Functions 将失败任务的输入和错误传递给回退任务? - How can I pass the input and error of my failing task to a fallback task using AWS Step Functions? AWS Step Functions - 将输入传递给另一个任务 - AWS Step Functions - Pass input to another task 在 AWS Step Functions 中将输入传递给输出 - Passthrough input to output in AWS Step Functions MaxConcurrency 属性如何适用于 AWS Step Functions 中的 Map 任务? - How does the MaxConcurrency attribute work for the Map Task in AWS Step Functions? 使用 Boto3 的 AWS 步骤函数任务成功回调 - AWS step functions task success callback using Boto3 如何参考 AWS step function 并行任务输出? - How reference AWS step function parallel task output? AWS Step Functions:使用键将状态数组输出转换为对象 - AWS Step Functions: Transform a state array output to an object with keys API网关正在覆盖AWS步骤功能状态输出 - API Gateway is Overwriting AWS Step Functions State Output 我在我的 AWS lambda 中启用了子流程输出 - 为什么这个日志输出没有被推送到 CloudWatch? - I have enabled subprocess output in my AWS lambda - why is this log output not being pushed to CloudWatch?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM