为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
料青山看我应如是 2023-03-29 16:01:44
我正在尝试在另一个 lambda 函数中调用一个 lambda 函数。我有 lambda 函数的调用动作,但是,我似乎无法让使用的 lambda 函数从发送 lambda 函数接收有效负载/正文。Lambda go doc 关于调用 lambda 函数这是我发送/调用 lambda 函数type Response events.APIGatewayProxyResponsefunc 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 中得到的响应......{200 map[Content-Type:application/json] "{\"message\":\"Something\"}" false} 
查看完整描述

4 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

我不得不将 body 对象也包含到有效负载中。


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


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



查看完整回答
反对 回复 2023-03-29
?
开满天机

TA贡献1786条经验 获得超12个赞

我认为您需要确保选择Use lambda proxy integration此选项可以让您接收有效负载数据。

//img1.sycdn.imooc.com//6423f0a50001a53606580313.jpg


查看完整回答
反对 回复 2023-03-29
?
qq_花开花谢_0

TA贡献1835条经验 获得超6个赞

问题似乎是您没有将正确的 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"

  }

}

如您所见,大多数字段都与 HTTP 内容相关,这是因为 API 网关旨在作为一种将您的 lambda 函数公开到网络的方式(也称为制作 REST API)。您可以更改 lambda 以接受新的事件类型(它必须是 JSON 可序列化类型)或用作字符串并自行序列化。


查看完整回答
反对 回复 2023-03-29
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

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

    }

}



查看完整回答
反对 回复 2023-03-29
  • 4 回答
  • 0 关注
  • 110 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信