Posting from AWS-API Gateway to Lambda

五迷三道 提交于 2019-12-03 02:55:01

When using Lambda Proxy Integration in API Gateway, the first parameter to your FunctionHandler is not the body of your POST, but is another API Gateway-created object, which let's call LambdaRequest. Try these changes to your sample code. Add:

public class LambdaRequest
{
   public string body { get; set; }
}

Change your handler prototype to:

public LambdaResponse FunctionHandler(LambdaRequest req, ILambdaContext context)

And inside FunctionHandler add:

ZipRequest input = JsonConvert.DeserializeObject<ZipRequest>(req.Body);

The full LambdaRequest object is documented under Input Format of a Lambda Function for Proxy Integration in the AWS docs, and contains HTTP headers, the HTTP method, the query string, the body, and a few other things.

This might not have been available when the OP asked the question, but when invoking a Lambda function using the API Gateway, specific response objects are provided.

As previously noted in the documentation Api Gateway Simple Proxy for Lambda Input Format, the API Gateway wraps the input arguments in a fairly verbose wrapper. It also expects a similarly verbose response object.

However, it is not necessary to create custom request and response objects. The AWS team provides the Amazon.Lambda.APIGatewayEvents library, which is also available on NuGet. This library includes APIGatewayProxyRequest and APIGatewayProxyResponse objects ready-made.

It is still necessary to manually deserialize the Body of the request, as it is a string, not a JSON object. I assume this was done for flexibility?

An example function could look like this. It's a modification of the default function provided by the AWS tools:

    public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        var bodyString = request?.Body;

        if (!string.IsNullOrEmpty(bodyString))
        {
            dynamic body = JsonConvert.DeserializeObject(bodyString);

            if (body.input != null)
            {
                body.input = body.input?.ToString().ToUpper();

                return new APIGatewayProxyResponse
                {
                    StatusCode = 200,
                    Body = JsonConvert.SerializeObject(body)
                };
            }
        }

        return new APIGatewayProxyResponse
        {
            StatusCode = 200
        };
    }

I also lost a lot of time trying to get a "Path Parameter" passed in on a Get method. For example, if you had a path such as

/appsetting/123

... then you'd have something configured like

By specifying the resource "appid" as {appid} it tells the API Gateway to capture this as a path variable.

One key discovery I found was that by posting in the body of a POST type action, my Lambda would work. Reading around on some other threads, I then discovered I can transform my path variable into a body of the GET action by:

  1. Selecting the GET value (as pictured)
  2. Clicking Integration Request
  3. Creating a mapping template as shown below

Now when I test, I'm able to plug in my appid value in only and get the proper result. Hope this helps someone.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!