doukan3504 2018-09-03 16:48
浏览 250

如何使用golang在另一个Lambda函数中调用Lambda函数

I'm trying to invoke a lambda func within another lambda func. I have the invokaction of the lambda function working, however, I can't seem to get the consuming lambda function to receive the payload/body from the sending lambda function.

Lambda go doc on invoking a lambda func

Here's my sending/invoking 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: &region,
    })
    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)
}

The response I get from invoked lambda...

{200 map[Content-Type:application/json] "{\"message\":\"Something\"}" false} 

My consuming lambda function

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)
}

The logs from the consuming lambda func

{ map[] map[] map[] map[] { { } map[] } false}
Json Unmarshalling error
unexpected end of JSON input
map[]

It seems that the consuming lambda function isn't receiving any events.APIGatewayProxyRequest, however I'm not sure why.

EDIT: My solution - I had to also include the json body object in the payload. Here's how I solved it

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.
  • 写回答

3条回答 默认 最新

  • doulianxi0587 2018-09-03 17:13
    关注

    Problem seems to be you're not passing a proper API Gateway Proxy Request Event to your consumer lambda:

    If you take a look at Amazon's sample events page you can see that API Gateway events have the following structure (more or less)

    {
      "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"
      }
    }
    

    As you can see most fields are related to HTTP stuff, that's because API Gateway is meant as a way to expose your lambda functions to the web (a.k.a. make REST APIS). You can either change your lambda to accept the new event type (it must be a JSON serializable type) or use as string and serialize it yourself.

    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog