Search code examples
postaws-lambdaserverless-framework

how to send post requests to AWS Lambda function created with serverless


TLDR

I cant figure out how to format my post request for my AWS Lambda API created with serverless

Current Implementation

I have a Lambda function created using the serverless framework. I have two functions; a function which prints out all modules and their version, and another that does a prediction on data sent via a post request. It handles dependency storage by mounting an EFS volume, here's the serverless.yml

service: test3Predict

plugins:
  - serverless-pseudo-parameters

custom:
  efsAccessPoint: fsap-**********
  LocalMountPath: /mnt/efs
  subnetsId: subnet-**********
  securityGroup: sg-**********

provider:
  name: aws
  runtime: python3.6
  region: us-east-2
  timeout: 20

package:
  exclude:
    - node_modules/**
    - .vscode/**
    - .serverless/**
    - .pytest_cache/**
    - __pychache__/**

functions:
  ohPredict:
    handler: handler.lambda_handler_OH
    environment: # Service wide environment variables
      MNT_DIR: ${self:custom.LocalMountPath}
    vpc:
      securityGroupIds:
        - ${self:custom.securityGroup}
      subnetIds:
        - ${self:custom.subnetsId}
    iamManagedPolicies:
      - arn:aws:iam::aws:policy/AmazonElasticFileSystemClientReadWriteAccess
    events:
      - http:
          path: ohPredict
          method: get
    fileSystemConfig:
      localMountPath: '${self:custom.LocalMountPath}'
      arn: 'arn:aws:elasticfilesystem:${self:provider.region}:#{AWS::AccountId}:access-point/${self:custom.efsAccessPoint}'

  test:
    handler: handler.test
    environment: # Service wide environment variables
      MNT_DIR: ${self:custom.LocalMountPath}
    vpc:
      securityGroupIds:
        - ${self:custom.securityGroup}
      subnetIds:
        - ${self:custom.subnetsId}
    iamManagedPolicies:
      - arn:aws:iam::aws:policy/AmazonElasticFileSystemClientReadWriteAccess
    events:
      - http:
          path: test
          method: get
    fileSystemConfig:
      localMountPath: '${self:custom.LocalMountPath}'
      arn: 'arn:aws:elasticfilesystem:${self:provider.region}:#{AWS::AccountId}:access-point/${self:custom.efsAccessPoint}'

It seems like the test is working; If I run sls deploy and enter the URL for my test function in a browser, I get the expected output.

Problem

The ohPredict function is not working as well. When I send it a post request with the requests python module,

url = 'https://****.execute-api.****.amazonaws.com/dev/ohPredict'
myobj = {"data": data}
x = requests.post(url, json=myobj)
res = eval(x.text)
print(res)

I get the following error:

{'message': 'Missing Authentication Token'}

I ran a test with a simple lambda function and a post request without using serverless, and that was all the code I needed. I figured I would try experimenting and supplying a few values, and I ended up with this:

url = 'https://****.execute-api.****.amazonaws.com/dev/ohPredict'
myobj = {"data": data}
x = requests.post(url, headers={'Authorization': 'FOO'}, json=myobj)
res = eval(x.text)
print(res)

which resulted in:

{'message': "Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header. Authorization=FOO"}

I tried playing around with supplying other values, and didn't get any change in the output. How can I get my post request to be recieved by my function?


Solution

  • As mentioned by yvesonline, the problem was the method. This was fixed by simply replacing method: get to method: post