Unable to integrate API gateway with aws lambda

2019-09-17 04:45发布

问题:

I am trying to integrate AWS API Gateway with an AWS lambda function. The integration works flawlessly until I use the 'Lambda Proxy integration' in my Integration Request.

When I check 'Use Lambda Proxy integration' in my integration request, I start getting:

"Execution failed due to configuration error: Malformed Lambda proxy response"

I googled around a bit and realized that I need to send back the response in a certain format:

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}

However, despite doing that, I still continue to see the same error. What am I doing wrong?

This is what my Lambda function looks like:

@Override
    public String handleRequest(Object input, Context context) {
        context.getLogger().log("Input: " + input);
        return uploadN10KWebsiteRepositoryToS3();
    }

    private String uploadN10KWebsiteRepositoryToS3() {
        /*BitbucketToS3Upload.JsonResponse jsonResponse = new BitbucketToS3Upload.JsonResponse();
        jsonResponse.body = "n10k_website repository uploaded to S3...";
        String jsonString = null;
        try {
            ObjectMapper mapper = new ObjectMapper();
            jsonString = mapper.writeValueAsString(jsonResponse);

            HashMap<String, Object> test = new HashMap<String, Object>();
            test.put("statusCode", 200);
            test.put("headers", null);
            test.put("body", "n10k_website repository uploaded to S3");
            test.put("isBase64Encoded", false);

            jsonString = mapper.writeValueAsString(test);
        }
        catch (Exception e) {
            int i = 0;
        }*/

        //return jsonString;
        return "{\"isBase64Encoded\":false, \"statusCode\":200, \"headers\":null, \"body\": \"n10k_website repository uploaded to S3\"}";
    }

When I test the API from API Gateway console, this is the response I get:

Received response. Integration latency: 4337 ms Mon Aug 07 00:33:45 UTC 2017 : Endpoint response body before transformations: "{\"isBase64Encoded\":false, \"statusCode\":200, \"headers\":null, \"body\": \"n10k_website repository uploaded to S3\"}"

Mon Aug 07 00:33:45 UTC 2017 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=0ff74e9d-7b08-11e7-9234-a1a04edc223f, Connection=keep-alive, Content-Length=121, Date=Mon, 07 Aug 2017 00:33:45 GMT, X-Amzn-Trace-Id=root=1-5987b565-7a66a2fd5fe7a5ee14c22633;sampled=0, Content-Type=application/json}

Mon Aug 07 00:33:45 UTC 2017 : Execution failed due to configuration error: Malformed Lambda proxy response

Mon Aug 07 00:33:45 UTC 2017 : Method completed with status: 502

If I un-check the 'Use Lambda Proxy integration', everything works okay. But I want to know why my response is malformed and how to fix it. Thanks!

回答1:

I figured it out. I was sending the response back in an incorrect manner.

The response had to be sent back as a POJO object directly rather than serializing the POJO and sending it back as a String. This is how I got it to work.

public class BitbucketToS3Upload implements RequestHandler<Object, JsonResponse> {

    @Data
    public static class JsonResponse {
        boolean isBase64Encoded = false;
        int statusCode = HttpStatus.SC_OK;
        String headers = null;
        String body = null;
    }

    @Override
    public JsonResponse handleRequest(Object input, Context context) {
        context.getLogger().log("Input: " + input);

        return uploadN10KWebsiteRepositoryToS3();
    }

    private JsonResponse uploadN10KWebsiteRepositoryToS3() {
        BitbucketToS3Upload.JsonResponse jsonResponse = new BitbucketToS3Upload.JsonResponse();
        jsonResponse.body = "n10k_website repository uploaded to S3";
        String jsonString = null;
        try {
            ObjectMapper mapper = new ObjectMapper();
            jsonString = mapper.writeValueAsString(jsonResponse);

            System.out.println(jsonString);

            //jsonString = mapper.writeValueAsString(test);
        }
        catch (Exception e) {
            int i = 0;
        }

        return jsonResponse;
        //return "{\"isBase64Encoded\":false, \"statusCode\":200, \"headers\":null, \"body\": \"n10k_website repository uploaded to S3\"}";
    }
} 

Hope this helps someone!