Docker化Go Lambda函数本地测试无法获取请求体问题
Docker化Go Lambda函数本地测试无法获取请求体的解决方法
我正在部署一个处理events.LambdaFunctionURLRequest的Docker化Go Lambda函数,本地通过AWS Lambda Runtime Interface Emulator(RIE)测试时无法获取请求体,但将代码打包为Zip部署到Lambda平台时可以正常运行。
相关代码及配置
main.go
package main import ( "context" "errors" "log" "net/http" "time" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func main() { lambda.Start(HandleRequest) } func init() { log.Println("Init Function") } func HandleRequest(ctx context.Context, request events.LambdaFunctionURLRequest) (ev events.LambdaFunctionURLResponse, err error) { log.Println("Received Handle Request") log.Println(request.Body) if request.Body == ""{ return ev, errors.New("No request body") } return }
Dockerfile
FROM golang AS build WORKDIR /app COPY . . RUN go mod download RUN go build -o main ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie RUN chmod 755 /usr/bin/aws-lambda-rie COPY entry.sh / RUN chmod 755 /entry.sh ENTRYPOINT [ "/entry.sh" ]
entry.sh
#!/bin/sh if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then exec /usr/bin/aws-lambda-rie "./main" else exec "$@" fi
问题原因
本地测试时,直接向RIE的/invocations端点发送原始JSON数据,但该端点要求传入的是Lambda调用事件格式,而非直接的HTTP请求体。部署到Lambda平台时,Lambda服务会自动将Function URL的HTTP请求转换为events.LambdaFunctionURLRequest结构的事件,因此能正确解析请求体;但本地测试时,必须手动构造符合该结构的事件数据。
解决方案
修改curl命令,将请求体包装成LambdaFunctionURLRequest对应的事件结构,示例如下:
curl --location --request POST 'http://localhost:9000/2015-03-31/functions/function/invocations' \ --header 'Content-Type: application/json' \ --data-raw '{ "version": "2.0", "rawPath": "/", "rawQueryString": "", "headers": { "Content-Type": "application/json" }, "requestContext": { "http": { "method": "POST", "path": "/" } }, "body": "{\"Hello There\": \"Some Data\"}", "isBase64Encoded": false }'
关键说明
body字段需要是字符串格式的JSON(将原始请求体转义后作为字符串值)- 如果请求体采用Base64编码,需将
isBase64Encoded设为true
修改后再次调用,request.Body就能正确获取到请求内容,不会再返回"No request body"错误。
内容的提问来源于stack exchange,提问作者Alexander Andrews
相关产品推荐
相关产品推荐

