[英]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。
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.