首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用golang在另一个Lambda函数中调用Lambda函数

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

Stack Overflow用户
提问于 2018-09-04 00:48:49
回答 4查看 5.6K关注 0票数 10

我正在尝试调用另一个lambda函数中的lambda函数。我让lambda函数的调用起作用了,但是,我似乎不能让使用lambda函数从发送lambda函数接收有效负载/主体。

Lambda go doc on invoking a lambda func

下面是我的发送/调用lambda函数

代码语言:javascript
复制
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)
}

我从调用lambda得到的响应...

代码语言:javascript
复制
{200 map[Content-Type:application/json] "{\"message\":\"Something\"}" false} 

我使用的lambda函数

代码语言:javascript
复制
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函数的日志

代码语言:javascript
复制
{ map[] map[] map[] map[] { { } map[] } false}
Json Unmarshalling error
unexpected end of JSON input
map[]

似乎使用lambda函数没有接收到任何events.APIGatewayProxyRequest,但是我不确定为什么。

编辑:我的解决方案-我还必须在有效负载中包含json body对象。下面是我解决这个问题的方法

代码语言:javascript
复制
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.
EN

回答 4

Stack Overflow用户

发布于 2018-09-04 01:13:04

问题似乎是您没有将正确的API Gateway代理请求事件传递给您的使用者lambda:

如果您查看Amazon's sample events page,您可以看到API Gateway事件具有以下结构(或多或少)

代码语言:javascript
复制
{
  "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 Gateway是一种将lambda函数公开给web的方式(也就是。制作REST APIS)。您可以更改lambda以接受新的事件类型(它必须是JSON可序列化类型),也可以将其用作字符串并自己序列化它。

票数 3
EN

Stack Overflow用户

发布于 2018-09-04 06:22:32

我认为您需要确保您选择的是Use lambda proxy integration,这将允许您接收有效负载数据。

票数 3
EN

Stack Overflow用户

发布于 2018-09-04 09:42:14

感谢@yorodm的输入,我还必须将body对象包含到有效负载中。

下面是使用golang在另一个lambda函数中调用lambda函数的完整解决方案

代码语言:javascript
复制
region := os.Getenv("AWS_REGION")
session, err := session.NewSession(&aws.Config{ // Use aws sdk to connect to dynamoDB
    Region: &region,
})
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52153716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档