I have code copied directly from the go section of the lambda tutorial
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/aws/aws-lambda-go/lambda"
)
type MyEvent struct {
Name string `json:"name"`
Age int `json:"age"`
}
type MyResponse struct {
Message string `json:"Answer"`
}
func HandleLambdaEvent(ctx context.Context, event MyEvent) (MyResponse, error) {
// event
eventJson, _ := json.MarshalIndent(event, "", " ")
log.Printf("EVENT: %s", eventJson)
return MyResponse{Message: fmt.Sprintf("%s is %d years old!", event.Name, event.Age)}, nil
}
func main() {
lambda.Start(HandleLambdaEvent)
}
I have created a .zip file, a role, attached that role and created the function on lambda.
I can invoke the function with aws lambda successfully
# aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"name": "Kevin", "age":62}' output.txt
# cat output.txt
{"Answer":"Kevin is 62 years old!"}
I created a function URL and can call it via awscurl (or curl)
# curl -X POST https://XXXXXXXXXX.lambda-url.us-east-1.on.aws/ \
-H 'Content-type: application/json' \
--user AWS_ID:AWS_KEY \
--aws-sigv4 "aws:amz:us-east-1:lambda \
-d '{"Name": "Kevin", "Age": 62}'
But the json doesn't go to the function (verified from the logs) and so isn't processed by my-function
{"Answer":" is 0 years old!"}
I have futzed with lambda:InvokeFunctionURL
but this didn't make any difference
CodePudding user response:
Lambda handles your request differently when you invoke the function through a function URL! This is not very intuitive, especially for people who are not familiar with the lambda integration in the Amazon API Gateway service, and I hope they make this more clear in the documentation. Here is the request and response payload structures. In your case, the POST payload is mapped to event.Body
, and you need to define "body" in the "MyEvent" struct like this,
type MyEvent struct {
...
Body string `json:body`
}
Hope this helps.
CodePudding user response:
MyEvent
does not match the payload your Lambda is actually receiving. When invoked via a Function URL, your Lambda receives an event with the shape of an API Gateway request.
The github.com/aws/aws-lambda-go package contains the request and response types for the various Lambda invoke events. APIGatewayV2HTTPRequest is the one you're looking for. Your POST payload is in Body
.
type APIGatewayV2HTTPRequest struct {
Version string `json:"version"`
RouteKey string `json:"routeKey"`
RawPath string `json:"rawPath"`
RawQueryString string `json:"rawQueryString"`
Cookies []string `json:"cookies,omitempty"`
Headers map[string]string `json:"headers"`
QueryStringParameters map[string]string `json:"queryStringParameters,omitempty"`
PathParameters map[string]string `json:"pathParameters,omitempty"`
RequestContext APIGatewayV2HTTPRequestContext `json:"requestContext"`
StageVariables map[string]string `json:"stageVariables,omitempty"`
Body string `json:"body,omitempty"`
IsBase64Encoded bool `json:"isBase64Encoded"`
}