douqiang7462 2018-09-05 20:24
浏览 98
已采纳

通过API GW调用时AWS Lambda Go函数未获取请求主体

First off, one might say this question is very similar to HTTP request body not getting to AWS lambda function via AWS API Gateway or Getting json body in aws Lambda via API gateway

However, none of these questions address using Golang, and the problem I have been having is finding an equivalent of the event parameter used everywhere in the Node.js documentation.

Here's my Lambda Function:

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

Problem: the MyReturn object is not being filled with any value when called from API GW. The line log.Print("Called by ", name) results in nothing being appended to the Called by string.

Request to API GW:

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

This is being performed in pure JS as follows:

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

And yet, the exact same body works when testing it from the AWS Lambda console.

Body:

{"name":"Bob"}
  • 写回答

1条回答 默认 最新

  • dqt20140129 2018-09-05 20:24
    关注

    Turns out, even though I wasn't able to find any documentation on this on a user-facing website, documentation does exist. Read this: https://github.com/aws/aws-lambda-go/blob/master/events/README_ApiGatewayEvent.md

    Here's the simplest way I've figured out so far to receive data from and respond to a request from 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)
    }
    

    In this case, the log.Print("Request body: ", name) line results in the exact request body being logged. Problem solved.

    Note: Also I didn't have to create that APIGWResponse object from the question, the events.APIGatewayProxyResponse is the exact same thing, already made for you. These objects are all inside this class: https://github.com/aws/aws-lambda-go/blob/master/events/apigw.go

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥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,如何解決?