1

I have been trying to deploy a lambda function and then make it accessible through API-gateway. My java function is in JAVA and this is the documentation I followed to create a simple AWS lambda function in JAVA:

https://docs.aws.amazon.com/lambda/latest/dg/java-handler-io-type-pojo.html

This is how my function handler looks:

package lambda;

    import com.amazonaws.services.lambda.runtime.Context;
    import com.amazonaws.services.lambda.runtime.RequestHandler;
    import lambda.axon.Path;

    public class shortestPath implements RequestHandler<RequestClass, ResponseClass>{

        public ResponseClass handleRequest(RequestClass request, Context context){
            String inputString = request.inputString;
            int steps = Path.stepsTo(inputString);
            return new ResponseClass(steps);

        }
    }

This is this request class:

package lambda;

public class RequestClass {
    String inputString;

    public String getInputString() {
        return inputString;
    }

    public void setInputString(String inputString) {
        this.inputString = inputString;
    }


    public RequestClass(String inputString) {
        this.inputString = inputString;
    }

    public RequestClass() {
    }
}

And this the response class:

package lambda;

public class ResponseClass {
    int steps;

    public ResponseClass(int steps) {
        this.steps = steps;
    }

    public ResponseClass() {
    }
    public int getSteps() {
        return steps;
    }

    public void setSteps(int steps) {
        this.steps = steps;
    }


}

I deploy this on aws and configure AWS api gateway to trigger it , everything works fine when I hit the end-point given by the API gateway when I use postman(https://www.getpostman.com/)

But trying the same through a browser gives me a CORS error:

Access to XMLHttpRequest at 'https://<hash>execute-api.us-east-1.amazonaws.com/dev' from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.

I tried enabling CORS in the API gateway console and then redeploying it: enter image description here

This Stackoverflow post(Configure CORS response headers on AWS Lambda?) says if I am using a lambda-proxy I should have the headers in the handler response itself, I am not sure what a proxy is but how I can do that with my current implementation of the Lambda function i.e. include custom headers in my Response

Snedden27
  • 1,870
  • 7
  • 32
  • 60
  • 1
    The error message cited in the question is due to your frontend code trying to add an access-control-allow-origin request header to the request. Remove whatever part of the code is doing that — because Access-Control-Allow-Origin is a response header, not a request header. – sideshowbarker Feb 25 '19 at 07:00
  • it seems like it solved my issue but still curious on how i can set reponse header in a java lambda trigger by the API gateway – Snedden27 Feb 25 '19 at 17:52

2 Answers2

3

To enable cors for a api gateway endpoint what connects to a lambda function, you have to enable cors for api endpoint (you have done) AND config your lambda function suport cors.

Follow my example:

// new respose class, replace for your class - ResponseClass
public class Response {

    private int statusCode; // http status code

    private Map<String, String> headers; // headers

    private String body; // body - what you want to return to client

    public Response(int statusCode, Map<String, String> headers, String body) {
        this.statusCode = statusCode;
        this.headers = headers;
        this.body = body;
    }

    public int getStatusCode() {
        return statusCode;
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public String getBody() {
        return body;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public void setHeaders(Map<String, String> headers) {
        this.headers = headers;
    }

    public void setBody(String body) {
        this.body = body;
    }

}

/// -------------

package lambda;

    import com.amazonaws.services.lambda.runtime.Context;
    import com.amazonaws.services.lambda.runtime.RequestHandler;
    import lambda.axon.Path;

    public class shortestPath implements RequestHandler<RequestClass, Response>{

        public Response handleRequest(RequestClass request, Context context){
            String inputString = request.inputString;
            int steps = Path.stepsTo(inputString);

            Map<String, String> headers = new HashMap<>();
            headers.put(Access-Control-Allow-Origin, "*"); // cors header, you can add another header fields

            return new Response(200, headers, "" + steps);
            // return new Response(200, headers, "{result: " + steps + "}");
            // simple json response. ex: {result: '3433"}
        }
    }

My way only effect when api gatewateway use LAMBDA-PROXY event config (default)

enter image description here

hoangdv
  • 15,138
  • 4
  • 27
  • 48
  • it gave me the headers in the response itself, what do you mean by lambda-proxy , is it something I need to do when make a new api in the api gateway , somehow I missed it – Snedden27 Feb 25 '19 at 17:57
  • We have two methods to control `request and response` of api gateway, `Lambda-Proxy vs Lambda Integration `. `Lambda-Proxy` is default option. When you use `Lambda-Proxy`, then your response http status code, header, data... are in lambda function's control. – hoangdv Feb 26 '19 at 01:02
  • I see, seems like the lambda -proxy is unchecked by default though – Snedden27 Feb 26 '19 at 03:37
  • Hey can you add the Lambda proxy at the top of your answer and if possible add a screenshot where the option is on AWS console . I think it would be better that way to explain to someone else – Snedden27 Feb 26 '19 at 13:56
0

you can enable cors from api gateway you can manage cors from lambda and manage the headers from lambda.

i would suggest to enable cors from api gateway and test it will work.

you can manage access-control-origin and headers like this way

'use strict';

module.exports.hello = function(event, context, callback) {

const response = {
  statusCode: 200,
  headers: {
    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS 
  },
  body: JSON.stringify({ "message": "Hello World!" })
};

callback(null, response);
};

you can refer this documentation : https://serverless.com/framework/docs/providers/aws/events/apigateway/

Harsh Manvar
  • 27,020
  • 6
  • 48
  • 102