ran*_*ndy 9 go amazon-web-services aws-sdk aws-lambda
我试图在另一个 lambda func 中调用一个 lambda func。我有 lambda 函数的调用,但是,我似乎无法让消耗 lambda 函数从发送 lambda 函数接收有效负载/主体。
Lambda go doc 关于调用 lambda func
这是我的发送/调用 lambda func
type Response events.APIGatewayProxyResponse
func Handler(ctx context.Context) (Response, error) {
region := os.Getenv("AWS_REGION")
session, err := session.NewSession(&aws.Config{ // Use aws sdk to connect to dynamoDB
Region: ®ion,
})
svc := invoke.New(session)
payload, err := json.Marshal(map[string]interface{}{
"message": "message to other lambda func",
})
if err != nil {
fmt.Println("Json Marshalling error")
}
input := &invoke.InvokeInput{
FunctionName: aws.String("invokeConsume"),
InvocationType: aws.String("RequestResponse"),
LogType: aws.String("Tail"),
Payload: payload,
}
result, err := svc.Invoke(input)
if err != nil {
fmt.Println("error")
fmt.Println(err.Error())
}
var m map[string]interface{}
json.Unmarshal(result.Payload, &m)
fmt.Println(m["body"])
body, err := json.Marshal(m["body"])
resp := Response{
StatusCode: 200,
IsBase64Encoded: false,
Headers: map[string]string{
"Content-Type": "application/json",
},
Body: string(body),
}
fmt.Println(resp)
return resp, nil
}
func main() {
lambda.Start(Handler)
}
Run Code Online (Sandbox Code Playgroud)
我从调用的 lambda 中得到的响应......
{200 map[Content-Type:application/json] "{\"message\":\"Something\"}" false}
Run Code Online (Sandbox Code Playgroud)
我消费的 lambda 函数
type Response events.APIGatewayProxyResponse
func Handler(ctx context.Context, req events.APIGatewayProxyRequest) (Response, error) {
fmt.Println(req)
var m map[string]interface{}
err := json.Unmarshal([]byte(req.Body), &m)
if err != nil {
fmt.Println("Json Unmarshalling error")
fmt.Println(err.Error())
}
fmt.Println(m)
body, _ := json.Marshal(map[string]interface{}{
"message": "Something",
})
resp := Response{
StatusCode: 200,
IsBase64Encoded: false,
Headers: map[string]string{
"Content-Type": "application/json",
},
Body: string(body),
}
return resp, nil
}
func main() {
lambda.Start(Handler)
}
Run Code Online (Sandbox Code Playgroud)
来自消费 lambda func 的日志
{ map[] map[] map[] map[] { { } map[] } false}
Json Unmarshalling error
unexpected end of JSON input
map[]
Run Code Online (Sandbox Code Playgroud)
似乎消耗 lambda 函数没有收到任何 events.APIGatewayProxyRequest,但是我不确定为什么。
编辑: 我的解决方案 - 我还必须在有效负载中包含 json body 对象。这是我解决的方法
body, err := json.Marshal(map[string]interface{}{
"name": "Jimmy",
})
type Payload struct {
Body string `json:"body"`
}
p := Payload{
Body: string(body),
}
payload, err := json.Marshal(p) // This should give you {"body":"{\"name\":\"Jimmy\"}"} if you print it out which is the required format for the lambda request body.
Run Code Online (Sandbox Code Playgroud)
感谢 @yorodm 的输入,我也必须将 body 对象包含到有效负载中。
这是使用 golang 在另一个 lambda 函数中调用 lambda 函数的完整解决方案
region := os.Getenv("AWS_REGION")
session, err := session.NewSession(&aws.Config{ // Use aws sdk to connect to dynamoDB
Region: ®ion,
})
svc := invoke.New(session)
body, err := json.Marshal(map[string]interface{}{
"name": "Jimmy",
})
type Payload struct {
// You can also include more objects in the structure like below,
// but for my purposes body was all that was required
// Method string `json:"httpMethod"`
Body string `json:"body"`
}
p := Payload{
// Method: "POST",
Body: string(body),
}
payload, err := json.Marshal(p)
// Result should be: {"body":"{\"name\":\"Jimmy\"}"}
// This is the required format for the lambda request body.
if err != nil {
fmt.Println("Json Marshalling error")
}
fmt.Println(string(payload))
input := &invoke.InvokeInput{
FunctionName: aws.String("invokeConsume"),
InvocationType: aws.String("RequestResponse"),
LogType: aws.String("Tail"),
Payload: payload,
}
result, err := svc.Invoke(input)
if err != nil {
fmt.Println("error")
fmt.Println(err.Error())
}
var m map[string]interface{}
json.Unmarshal(result.Payload, &m)
fmt.Println(m["body"])
invokeReponse, err := json.Marshal(m["body"])
resp := Response{
StatusCode: 200,
IsBase64Encoded: false,
Headers: map[string]string{
"Content-Type": "application/json",
},
Body: string(invokeReponse),
}
fmt.Println(resp)
return resp, nil
Run Code Online (Sandbox Code Playgroud)
问题似乎是您没有将正确的 API 网关代理请求事件传递给您的消费者 lambda:
如果您查看Amazon 的示例事件页面,您可以看到 API 网关事件具有以下结构(或多或少)
{
"path": "/test/hello",
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, lzma, sdch, br",
"Accept-Language": "en-US,en;q=0.8",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
"Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
"X-Forwarded-For": "192.168.100.1, 192.168.1.1",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"pathParameters": {
"proxy": "hello"
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "us4z18",
"stage": "test",
"requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9",
"identity": {
"cognitoIdentityPoolId": "",
"accountId": "",
"cognitoIdentityId": "",
"caller": "",
"apiKey": "",
"sourceIp": "192.168.100.1",
"cognitoAuthenticationType": "",
"cognitoAuthenticationProvider": "",
"userArn": "",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
"user": ""
},
"resourcePath": "/{proxy+}",
"httpMethod": "GET",
"apiId": "wt6mne2s9k"
},
"resource": "/{proxy+}",
"httpMethod": "GET",
"queryStringParameters": {
"name": "me"
},
"stageVariables": {
"stageVarName": "stageVarValue"
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,大多数字段都与 HTTP 内容相关,这是因为 API Gateway 是一种将 lambda 函数公开到网络的方式(也称为 REST APIS)。您可以更改 lambda 以接受新的事件类型(它必须是 JSON 可序列化类型)或用作字符串并自行序列化。
| 归档时间: |
|
| 查看次数: |
5078 次 |
| 最近记录: |