0

I am creating a demo project for learning Serverless framework.

I have a Lambda Function taking input of two parameters from event object in following way:

operandOne = event["operandOne"] operandTwo = event["operandTwo"]

I have created a API Gateway which calls this lambda function with this parameters.

I have been following this link till now for my answer but still haven't figured out how to implement. - AWS Lambda: Clarification on retrieving data from event object

Above given answer has three ways to pass the parameter, from which I am interested in third option. "3) Directly on the event object"

It can be done with the help of mapping template from AWS console. But I am trying to find a way to use cloud formation(Writing mapping template in yaml file) for the same purpose for learning.

Robin
  • 39
  • 1
  • 7

3 Answers3

1

But I am trying to find a way to use cloud formation(Writing mapping template in yaml file) for the same purpose for learning.

For that you would have to provide your template in RequestTemplates of your AWS::ApiGateway::Method:

A map of Apache Velocity templates that are applied on the request payload. The template that API Gateway uses is based on the value of the Content-Type header that's sent by the client.

A generic example from the link you provided would be:

        RequestTemplates: 
          application/json: {"hello": $input.params('$hello')}            
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • I tried the same using the following code: `"{ \"operator1\": \"$input.params('$operator1')\", \"operator2\": \"$input.params('$operator2')\" }" `Just to confirm $input.params is used when the data is being sent using GET. Can you please what I am doing wrong – Robin Jul 16 '20 at 16:01
1

When you have a post request from API Gateway connected to a Lambda function, you can access all body parameters in the event object via event.body. If the body was stringified using JSON, you can just do:

const body = JSON.parse(event.body)
const operandOne = body.operandOne
const operandTwo = body.operandTwo

No need for any templates

Gareth McCumskey
  • 1,510
  • 7
  • 12
  • Thanks for the reply. I have used the above specified way. But what I am trying to achieve is to create a front end to access lambda and also use it with other AWS service directly. So to achieve this I need to keep the implementation on Lambda side clean and simple without adding more flags as who requested the data. Like by accessing object directly from event object of Lambda. The only problem I am having when the data is sent is I need to access the data from event["body"] rather than directly from event. – Robin Jul 16 '20 at 15:45
  • 1
    I am not sure why the concern with the event object. Lambda's were meant to receive event objects from AWS services and then the Lambda gets the opportunity at the very least to transform that object before passing it to the next service in the queue. So really, the solution is to have a Lambda receive the API Gateway event object, generate the object you want and manually invoked a Lambda function with your constructed object: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#invokeAsync-property – Gareth McCumskey Jul 17 '20 at 16:51
  • True I am currently learning AWS services so exploring all different options. Will try these too. But I was just trying to achieve direct integration of API Gateway and one Lambda function. – Robin Jul 17 '20 at 18:06
0

My input to the API Gateway is as follows:

{
    operandOne: 2
    operandTwo: 3
}

API Gateway needs a body mapping template to map this parameter for lambda function and send them in event object. It can be in two ways

  1. Using AWS Console
  2. Using cloud formation template

I wanted to use the second approach.

Here is what I have written in cloud_formation.template.yml file

APIGatewayDefinition:
  Type: 'AWS::Serverless::Api'
  Properties:
    basePath: /
      paths:
        /insert:
          post:
            summary:
            description:
            consumes:
             - application/json
            produces:
             - application/json
            x-amazon-apigateway-integration:
              requestTemplates:
                application/json: "#set ($root=$input.path('$')) { \"operandOne\": \"$root.operandOne\", \"operandOne\": \"$root.operandOne\" }"
              type: aws
....

Then I could access both the variable in Lambda directly from event object rather than from body in event object.

operandOne = event["operandOne"]
operandTwo = event["operandTwo"]

For reference: AWS Lambda: Clarification on retrieving data from event object

Robin
  • 39
  • 1
  • 7