通过 API GW 调用时,AWS Lambda Go 函数未获取请求正文

AWS Lambda Go function not getting request body when called via API GW

首先,有人可能会说这个问题与 or

非常相似

但是,none 这些问题是使用 Golang 解决的,我一直遇到的问题是找到 Node.js 文档中随处使用的 event 参数的等效项。

这是我的 Lambda 函数:

package main

import (
    "context"
    "encoding/json"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-lambda-go/events"
    "log"
)

type MyReturn struct {
    Response string `json:"response"`
}

type APIGWResponse struct {
    IsBase64Encoded bool              `json:"isBase64Encoded"`
    StatusCode      int               `json:"statusCode"`
    Headers         map[string]string `json:"headers"`
    Body            string            `json:"body"`
}

func handle(ctx context.Context, name MyReturn) (APIGWResponse, error) {
    log.Print("Called by ", name)
    log.Print("context ", ctx)
    headers := map[string]string{"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept"}

    code := 200
    response, error := json.Marshal(myReturn{Response:"Hello, " + name.Body})
    if error != nil {
        log.Println(error)
        response = []byte("Internal Server Error")
        code = 500
    }

    return APIGWResponse{true, code, headers, string(response)}, nil
}

func main() {
    lambda.Start(handle)
}

问题:当从 API GW 调用时,MyReturn 对象没有被填充任何值。 log.Print("Called by ", name) 行不会将任何内容附加到 Called by 字符串。

请求 API GW:

 POST -> body: '{"name":"Bob"}', headers: {'Content-Type': 'application/json'}

这是在纯 JS 中执行的,如下所示:

const BASE_URL = "https://my_api_id.execute-api.us-east-1.amazonaws.com/prod/";
const TRIGGER_URL = "my_lambda_function";

function toGW() {
    fetch(BASE_URL + TRIGGER_URL, {
        method: 'POST',
        body: '{"name":"Bimesh"}',
        headers:{
            'Content-Type': 'application/json'
        }
    })
    .then(data => data.json())
    .then(json => console.log(json))
    .catch(error => console.log(error));
}

然而,当从 AWS Lambda 控制台对其进行测试时,完全相同的主体可以正常工作。

正文:

{"name":"Bob"}

事实证明,即使我无法在面向用户的网站上找到关于此的任何文档,文档也确实存在。读这个:https://github.com/aws/aws-lambda-go/blob/master/events/README_ApiGatewayEvent.md

这是迄今为止我想出的从 API GW 接收数据和响应请求的最简单方法:

package main

import (
    "context"
    "encoding/json"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-lambda-go/events"
    "log"
)

type myReturn struct {
    Response string `json:"response"`
}

func handle(ctx context.Context, name events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    log.Print("Request body: ", name)
    log.Print("context ", ctx)
    headers := map[string]string{"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept"}

    code := 200
    response, error := json.Marshal(myReturn{Response:"Hello, " + name.Body})
    if error != nil {
        log.Println(error)
        response = []byte("Internal Server Error")
        code = 500
    }

    return events.APIGatewayProxyResponse {code, headers, string(response), false}, nil
}

func main() {
    lambda.Start(handle)
}

在这种情况下,log.Print("Request body: ", name) 行会记录准确的请求正文。问题已解决。

注意:另外,我不必根据问题创建 APIGWResponse 对象,events.APIGatewayProxyResponse 是完全相同的东西,已经为您准备好了。这些对象都在这个class里面:https://github.com/aws/aws-lambda-go/blob/master/events/apigw.go