request.Body在通过HTTP网关和测试GUI时具有不同的值。

huangapple go评论71阅读模式
英文:

request.Body has a different value through http gateway than through the test GUI

问题

我从https://github.com/aws/aws-lambda-go/blob/master/events/README_ApiGatewayEvent.md获取了这段代码:

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID)
	fmt.Printf("Body size = %d.\n", len(request.Body))

	fmt.Println("Headers:")
	for key, value := range request.Headers {
		fmt.Printf("    %s: %s\n", key, value)
	}

	log.Printf("%v", request.Body)

	return events.APIGatewayProxyResponse{Body: request.Body, StatusCode: 200}, nil
}

func main() {
	lambda.Start(handleRequest)
}

我只添加了一行日志:log.Printf("%v", request.Body)

当我编译并使用lambda测试GUI时,我发送了以下内容:

{"body":"[{\"id\":\"123\"}]"}

在选项卡中的日志显示如下:

2021/08/16 08:51:50 [{"id":"123"}]

然而,当我执行以下操作时:

curl https://qmk743l1p0.execute-api.us-east-1.amazonaws.com/default/simplegateway -d '{"body":"[{\"id\":\"123\"}]"}' --header "Content-Type: application/json"

我在CloudWatch日志中得到了以下内容:

2021/08/16 08:56:07 {"body":"[{\"id\":\"123\"}]"}

我不知道为什么通过HTTP网关时request.body会有两个不同的值。

如何在lambda测试GUI和HTTP API网关中获取预期的body值?

英文:

I got this code from https://github.com/aws/aws-lambda-go/blob/master/events/README_ApiGatewayEvent.md :

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID)
	fmt.Printf("Body size = %d.\n", len(request.Body))

	fmt.Println("Headers:")
	for key, value := range request.Headers {
		fmt.Printf("    %s: %s\n", key, value)
	}

	log.Printf("%v", request.Body)

	return events.APIGatewayProxyResponse{Body: request.Body, StatusCode: 200}, nil
}

func main() {
	lambda.Start(handleRequest)
}

I only added: the log: log.Printf("%v", request.Body)

When I compile and use the lambda test GUI, I send this:

{"body":"[{\"id\":\"123\"}]"}

and the log in the tab shows this:

2021/08/16 08:51:50 [{"id":"123"}]

However, when I do this:

curl https://qmk743l1p0.execute-api.us-east-1.amazonaws.com/default/simplegateway -d '{"body":"[{\"id\":\"123\"}]"}' --header "Content-Type: application/json"

I get this in the CloudWatch logs:

2021/08/16 08:56:07 {"body":"[{\"id\":\"123\"}]"} 

I have no idea why request.body would have two different values when going through the http gateway.

How do I get the intended "body" in both the lambda test GUI and in through the http API gateway?

答案1

得分: 3

这是因为你的处理程序在两种情况下具有相同的签名,但根据代理请求的方式,其含义不同。

当你从Lambda GUI发送请求时,请求体会直接解组为events.APIGatewayProxyRequest。该结构体定义了一个字段:

Body string `json:"body"`

因此,当你发送载荷{"body":"[{\"id\":\"123\"}]}"时,json.Unmarshal会将该字段填充为JSON的body属性的值,即[{"id":"123"}]

当相同的请求通过API Gateway进行代理时,Gateway会构造一个包含原始载荷的AWS事件,因此它可能看起来像这样:

{
    ...
    "body": "{\"body\":\"[{\"id\":\"123\"}]\"}"
}

然后,事件才会解组为events.APIGatewayProxyRequest结构体,Body字段的值为{"body":"[{\"id\":\"123\"}]}"

英文:

This happens because your handler has the same signature in both cases, but what that implies differs based on what is proxying your request.

When you send the request from the Lambda GUI, the body gets unmarshaled into the events.APIGatewayProxyRequest straight away. That struct has a field defined as:

Body string `json:"body"`

So when you send the payload {"body":"[{\"id\":\"123\"}]"}, json.Unmarshal populates that field with the value of the JSON body property, which is [{"id":"123"}]

When the same request is proxied through the API Gateway, the Gateway constructs a AWS event that contains your payload as-is, so it will probably look like:

{
    ...
    "body": "{\"body\":\"[{\"id\":\"123\"}]\"}\"
}

And only then the event is unmarshaled into the events.APIGatewayProxyRequest struct, resulting in the Body field having the value {"body":"[{\"id\":\"123\"}]"}.

答案2

得分: 2

尽管我对Lambda GUI不太熟悉,但我怀疑在那里你需要输入请求的JSON表示(包括头部和正文),但是当使用curl发送时,你不需要包装正文(-d),所以只需像这样发送它[{"id":"123"}],因为这是正文应该包含的内容。

英文:

Though i am not familiar with the lambda GUI i suspect that there you input the json representation of the request (with headers and body), but when sending via curl, you don't need to wrap the body (-d), so just send it like this [{\"id\":\"123\"}] as this is what the body should contain.

huangapple
  • 本文由 发表于 2021年8月16日 17:12:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/68800162.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定