When running a test event with AWS Lambda (accessed via AWS Console) I am able to pass in the following body and properly parse the data to a custom struct
Custom struct:
type ContactForm struct {
Phone int `json:"phone"`
Email string `json:"email"`
Business string `json:"business"`
Message string `json:"message"`
Name string `json:"name"`
File_data *string `json:"file_data"`
File_name *string `json:"file_name"`
Uri *string
}
Event JSON:
{
"email": "email.com",
"phone": 80077777,
"business": "business",
"message": "message",
"name": "name"
}
When attempting to hit the lambda via a function URL using postman or an XHR request the body when parsed defaults to nil, 0, and empty string values showing that it is not able to read the json body. This is the entry point of the golang lambda that should pass in the object, but fails when done via function URL
func HandleRequest(ctx context.Context, contactForm ContactForm) {
if contactForm.File_data != nil && contactForm.File_name != nil {
uri := create_file(*contactForm.File_data, *contactForm.File_name)
contactForm.Uri = &uri
}
fmt.Printf("%v", contactForm)
body := create_email_body(contactForm)
sendEmail(contactForm.Business, body)
}
Is there additional logic that needs to be done when parsing via an endpoint in comparison to using a Test Event?
2
Answers
So depending on how you’re posting the data to the function e.g ApiGatewayProxyRequest or in your case LambdaFunctionURLRequest, the event might contain extra fields and metadata. I’d suggest you log the raw event, see https://docs.aws.amazon.com/lambda/latest/dg/golang-logging.html and base your struct off of what you see actually posted to the function. This was the case when I’ve run into circumstances like yours.
Also, there is a predefined package you can use to define your events: "github.com/aws/aws-lambda-go/events". I think events.LambdaFunctionURLRequest is what you need to set in your handler. Then you can parse the JSON from the body of this payload. See https://pkg.go.dev/github.com/aws/aws-lambda-go/events#LambdaFunctionURLRequest.
Here is the same method/logic from GoPlayground.
You’ll need to do some validation of the data to make sure it’s actually json or catch the cases in which the payload is bad. This is good programming in general, so I’m assuming you’d additionally deal with edge cases in which the body didn’t serialize into the struct.
When the Lambda function is invoked through the function HTTP URL you receive the payload in the following format:
You can find more information about the format here.
So, the second parameter of the
HandleRequest
should be astruct
with that format. YourContactForm
is actually thebody
of the request. Be aware that body may be a string, so you’d need to parse it.