11

I'm submitting a form to a Lambda function deployed by serverless, here's the yml:

functions:
  hello:
    handler: handler.hello
    events:
      - http: POST hello

Now my hello function is:

module.exports.hello = (event, context, callback) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Se222rverless v1.0! Your function executed successfully!',
      input: event,
    }),
  };

  callback(null, response);
};

I can see on the output that the variables were passed, but they are stored in the event.body property as such:

 "body":"email=test%40test.com&password=test12345"

Now I can access this string, but I can't read individual variables from it, unless I do some regex transformation which, I believe, would not be the case in such a modern stack such as serverless/aws.

What am I missing? How do I read the individual variables?

sigmaxf
  • 7,998
  • 15
  • 65
  • 125
  • Can't you change your POST request to use `application/json` as content-type? It'll be easier for you since you can just use `JSON.parse(event.body)` to get the payload. – Noel Llevares Mar 15 '18 at 01:40
  • this seems interesting, how can I set the post request to use the application/json? I tried in the form but it's still submitting in a encoded string – sigmaxf Mar 15 '18 at 16:22
  • https://stackoverflow.com/questions/22195065/how-to-send-a-json-object-using-html-form-data – Stevko Mar 15 '18 at 17:06
  • it is a good idea but it behaves weirdly, JSON.stringify($(element).serializeArray()) gives me back not {key:data} but {name:key, value:data} making it harder to read. just serialize() returns the same querystring – sigmaxf Mar 15 '18 at 20:13

3 Answers3

9

It looks like your Serverless endpoint is receiving data with Content-Type: application/x-www-form-urlencoded. You could update the request to use JSON data instead to access the post variables the same way you would other JavaScript objects.

Assuming this isn't an option; you could still access your post body data using the node querystring module to parse the body of the request, here is an example:

const querystring = require('querystring');

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

  // Parse the post body
  const data = querystring.parse(event.body);

  // Access variables from body
  const email = data.email;

  ...

}

Just remember if some of the parameters in the post body use names that are invalid JavaScript object identifiers to use the square bracket notation, e.g.:

const rawMessage = data['raw-message'];
bdh
  • 127
  • 1
  • 2
  • 8
0

You can use a the Node querystring module to parse the POST body.

Jacob Krall
  • 28,341
  • 6
  • 66
  • 76
  • 1
    Is this the "official" way to do it though? It just seems to me that there would be a simpler way of doing such a common task. Parsing with a node module would be pretty much the same as parsing with a custom js function. – sigmaxf Mar 15 '18 at 00:01
  • It’s built into Node, so I can’t think of a more official way to do it. – Jacob Krall Mar 15 '18 at 00:02
0

The handler documentation for the various programming models implies that the event type from the API Gateway is a low level stream. That means you have to use other methods to extract the body content from the POST.

Input Format

{
    "resource": "Resource path",
    "path": "Path parameter",
    "httpMethod": "Incoming request's method name"
    "headers": {Incoming request headers}
    "queryStringParameters": {query string parameters }
    "pathParameters":  {path parameters}
    "stageVariables": {Applicable stage variables}
    "requestContext": {Request context, including authorizer-returned key-value pairs}
    "body": "A JSON string of the request payload."
    "isBase64Encoded": "A boolean flag to indicate if the applicable request payload is Base64-encode"
}

Dotnet Only the System.IO.Stream type is supported as an input parameter by default.

Python event – This parameter is usually of the Python dict type. It can also be list, str, int, float, or NoneType type.

Stevko
  • 4,345
  • 6
  • 39
  • 66
  • what about in javascript? – sigmaxf Mar 15 '18 at 20:00
  • the above Input Format is for the JS event object. @Jacob Krall suggestion to parse the body with querystring seems to be the most effective way to do so in javascript lambda. – Stevko Mar 15 '18 at 20:11