我正在尝试在另一个Lambda函数中调用Lambda函数。我可以使用lambda函数,但是,似乎无法从使用的lambda函数中接收发送的lambda函数的有效负载/主体。
Lambda go doc on invoking a lambda func
这是我的发送/调用lambda函数
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)
}
我从被调用的lambda得到的响应...
{200 map[Content-Type:application/json] "{\"message\":\"Something\"}" false}
我正在使用的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)
}
使用中的lambda函数的日志
{ map[] map[] map[] map[] { { } map[] } false}
Json Unmarshalling error
unexpected end of JSON input
map[]
似乎使用中的lambda函数没有收到任何事件。APIGatewayProxyRequest,但是我不确定为什么。
编辑: 我的解决方案-我还必须在有效负载中包含json主体对象。这是我解决的方法
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.
答案 0 :(得分:2)
问题似乎是您没有将适当的API网关代理请求事件传递给您的使用者lambda:
如果您查看MDN,您会发现API Gateway事件具有以下结构(或多或少)
{
"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"
}
}
如您所见,大多数字段都与HTTP相关,这是因为API网关是一种将lambda函数公开到网络的方法(也称为make REST APIS)。您可以更改lambda以接受新的事件类型(它必须是JSON可序列化的类型),也可以用作字符串并自己对其进行序列化。
答案 1 :(得分:2)
答案 2 :(得分:0)
由于@yorodm的输入,我还必须将主体对象也包含在有效载荷中。
这是使用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
答案 3 :(得分:0)
AWS SDK 有一个例子: https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/go/example_code/lambda/aws-go-sdk-lambda-example-run-function.go
package main
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/lambda"
"encoding/json"
"fmt"
"os"
"strconv"
)
type getItemsRequest struct {
SortBy string
SortOrder string
ItemsToGet int
}
type getItemsResponseError struct {
Message string `json:"message"`
}
type getItemsResponseData struct {
Item string `json:"item"`
}
type getItemsResponseBody struct {
Result string `json:"result"`
Data []getItemsResponseData `json:"data"`
Error getItemsResponseError `json:"error"`
}
type getItemsResponseHeaders struct {
ContentType string `json:"Content-Type"`
}
type getItemsResponse struct {
StatusCode int `json:"statusCode"`
Headers getItemsResponseHeaders `json:"headers"`
Body getItemsResponseBody `json:"body"`
}
func main() {
// Create Lambda service client
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
client := lambda.New(sess, &aws.Config{Region: aws.String("us-west-2")})
// Get the 10 most recent items
request := getItemsRequest{"time", "descending", 10}
payload, err := json.Marshal(request)
if err != nil {
fmt.Println("Error marshalling MyGetItemsFunction request")
os.Exit(0)
}
result, err := client.Invoke(&lambda.InvokeInput{FunctionName: aws.String("MyGetItemsFunction"), Payload: payload})
if err != nil {
fmt.Println("Error calling MyGetItemsFunction")
os.Exit(0)
}
var resp getItemsResponse
err = json.Unmarshal(result.Payload, &resp)
if err != nil {
fmt.Println("Error unmarshalling MyGetItemsFunction response")
os.Exit(0)
}
// If the status code is NOT 200, the call failed
if resp.StatusCode != 200 {
fmt.Println("Error getting items, StatusCode: " + strconv.Itoa(resp.StatusCode))
os.Exit(0)
}
// If the result is failure, we got an error
if resp.Body.Result == "failure" {
fmt.Println("Failed to get items")
os.Exit(0)
}
// Print out items
if len(resp.Body.Data) > 0 {
for i := range resp.Body.Data {
fmt.Println(resp.Body.Data[i].Item)
}
} else {
fmt.Println("There were no items")
}
}