3

After enabled CORS on API gateway, here is the request I sent to the http end point:

    $.ajax({
        type: 'put',
        url: 'https://xxxxx.execute-api.us-east-1.amazonaws.com/dev/artist/application/julian_test',
        data: {params: {param1: "543543", param2: "fdasghdfghdf", test: "yes"}},
        success: function(msg){
            console.log(msg);
        },
        error: function(msg){
            console.log(msg);
        }
    });

Here is the lambda function(I'm using node serverless package, and no mistakes on the code):

module.exports.julian_test = (event, context, callback) => {
    console.log(event);
    console.log(event.body);

var response_success = {
    statusCode: 200,
    headers: {
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        firstUser: {
            username: "Julian",
            email: "awesome"
        },
        secondUser: {
            username: "Victor",
            email: "hello world"
        },
        thirdUser: {
            username: "Peter",
            email: "nice"
        }
    })
};
    callback(null, response_success);
};

The console.log(event.body) logs out : params%5Bparam1%5D=543543&params%5Bparam2%5D=fdasghdfghdf&params%5Btest%5D=yes

, which is not the format I want. I checked the OPTIONS Integration Request / body mapping template, here is the snapshot.

enter image description here

I tried to delete the "application/json" but after that I receive the following response:

XMLHttpRequest cannot load https://xxxxxx.execute-api.us-east-1.amazonaws.com/dev/artist/application/julian_test. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 500.

Does anyone know how to get a raw string request body in the back-end lambda? Please help!

Pano
  • 2,099
  • 6
  • 16
  • 24

4 Answers4

4

The screenshot is for OPTIONS method which is used for CORS.

Your actual Lambda function call is likely made via POST method. Please check the integration request Body mapping templates under the POST method. If it is setup to pass through body (which is default), the body from your input request should be passed to Lambda as is.

Please use test feature in API Gateway console to see how the input is transformed to integration request. That should help you to debug.

Balaji
  • 1,028
  • 8
  • 12
1

Two things here:

Firstly, under your API Gateway resource, go to Method Response and make sure you have a response for 200 OK mapped.

Secondly, under your API Gateway resource, go to Integration Request, under Body Mapping Templates select application/json and enter the following code in the template text editor:

{
  "method": "$context.httpMethod",
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "queryParams": {
    #foreach($param in $input.params().querystring.keySet())
    "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "pathParams": {
    #foreach($param in $input.params().path.keySet())
    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end

    #end
  }  
}

When this is applied, you can access your request object as such: (Node.js)

  console.log('Body:', event.body);
  console.log('Headers:', event.headers);
  console.log('Method:', event.method);
  console.log('Params:', event.params);
  console.log('Query:', event.query);

Took me a while to figure this out, props to Kenn Brodhagen for the explanation: tutorial

Tom Nijs
  • 3,835
  • 3
  • 22
  • 40
  • 16
    This doesn't actually allow you to get to the raw body string of the request, it is parsing it and returning it as json. Is there any way of getting the original string, as I need to do some signing request. – CosmicChild Dec 07 '17 at 15:51
0

The only way get real raw AWS Lambda request is via Stream for Handler Input.

As per documentation:

The input payload must be valid JSON but the output stream does not carry such a restriction. Any bytes are supported.

Example of streaming AWS Lambda input and output in Java:

public void handler(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        int letter;
        while((letter = inputStream.read()) != -1)
        {
            outputStream.write(Character.toUpperCase(letter));
        }
    }
Donnie
  • 200
  • 1
  • 6
0

Tom's answer above adds everything except the raw request body. Adding this line to that mapping template allowed me to verify requests as per Slack's documentation:

"rawBody": $util.escapeJavaScript($input.body)

VirtualWolf
  • 653
  • 13
  • 23