Функция AWS Lambda Go не получает тело запроса при вызове через API GW

Во-первых, можно было бы сказать, что этот вопрос очень похож на то, что тело HTTP-запроса не попадает в лямбда-функцию AWS через AWS API Gateway или Получение тела json в AWS Lambda через шлюз API

Однако ни один из этих вопросов не касается использования Голанга, и проблема, с которой я столкнулся, заключается в нахождении эквивалента event параметр, используемый везде в документации Node.js.

Вот моя лямбда-функция:

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

Проблема: MyReturn объект не заполняется никаким значением при вызове из API GW. Линия 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"}

1 ответ

Решение

Оказывается, хотя я не смог найти никакой документации по этому вопросу на веб-сайте, ориентированном на пользователя, документация существует. Прочитайте это: 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 это то же самое, уже сделано для вас. Эти объекты находятся внутри этого класса: https://github.com/aws/aws-lambda-go/blob/master/events/apigw.go

Что ж, у меня недостаточно репутации, чтобы ответить на комментарий @laurids... поэтому я думаю, что Stackru заставляет меня дать новый ответ (?). лол

laurids Я был удивлен, обнаружив, что когда я отправляю следующее событие лямбда-теста, я получаю пустое тело запроса в golang

{
  "name": "Bob"
}

Я должен сделать это, чтобы установить тело запроса. Надеюсь, это поможет!

{
  "body": "{\"name\": \"Bob\"}"
}
Другие вопросы по тегам