Lambda function as image, how to find your handler URI

0

Hello,

I have followed all of the tutorials on how to build an AWS Lambda function as a container image. I am also using the AWS SAM SDK as well. What I don't understand is how do I figure out my end-point URL mapping from within my image to the Lambda function?

For example in my docker image that I am using the AWS Python 3.9 image where I install some other packages and my python requirements and my handler is defined as:

summarizer_function_lambda.postHandler

My python file being copied into the image is the same name as above but without the .postHandler

My AWS SAM Template has:

AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: AWS Lambda dist-bart-summarizer function

More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst

Globals: Function: Timeout: 3

Resources: DistBartSum: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: FunctionName: DistBartSum ImageUri: <my-image-url> PackageType: Image Events: SummarizerFunction: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /postHandler Method: POST

So what is my actual URI path to do my POST call either locally or once deployed on Lambda??

When I try and do a CURL command I get an "{"message": "Internal server error"}% "

curl -XPOST "https://<my-aws-uri>/Prod/postHandler/" -d '{"content": "Test data.\r\n"}'

So I guess my question is how do you "map" your handler definitions from within a container all the way to the end point URI?

asked 2 years ago1288 views
2 Answers
1

The url you are creating looks correct. You can reference the API Gateway tutorial and see that they have a section showing how to build the URL:

To test the deployed API using cURL:
1. Open a terminal window.
2. Copy the following cURL command and paste it into the terminal window, replacing *r275xc9bmd* with your API's API ID and *us-east-1* with the region where your API is deployed.

curl -v -X POST \
  'https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld?name=John&city=Seattle' \
  -H 'content-type: application/json' \
  -H 'day: Thursday' \
  -d '{ "time": "evening" }'

Based on what you provided, it looks like API Gateway's Stage name is "Prod" so I would expect the following to work after replacing r275xc9bmd with your API's API ID and us-east-1 with the region:

curl -v -X POST \
  'https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/Prod/postHandler' \
  -H 'content-type: application/json' \
  -d '{ "content": "Test data.\r\n" }'

You might want to confirm API Gateway and Lambda is configured correctly and look at the CloudWatch logs to find the error.

AWS
answered 2 years ago
profile picture
EXPERT
reviewed 15 days ago
  • This makes sense for a API gateway deployment, but what is the end point URI for a Lambda Function URI? Meaning no gateway deployment. So in my example I have the following Lambda Function URI: https://<my_unique_id>.lambda-url.us-east-2.on.aws/

    When I try and do a CURL to that URL I just get: Internal Server Error%

    Should it be: https://<my_unique_id>.lambda-url.us-east-2.on.aws/postHandler In my example above with my python code?

  • Sp just to close this whole thing it, when it comes to a container Lambda function whatever you "lambda_function.handler" is called will work with your top level Function URL, i.e:

    'https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/ -H 'content-type: application/json'
    -H 'day: Thursday'
    -d '{ "content": "something" }'

0

When you create a Lambda function, regardless if using the zip file format or the container image format, the function should have a Lambda handler. The handler is the entry point to your function. This is where you write your business logic. If you are using Python, it would look like:

def handler(event, context):
    print (event)

    return {
        'statusCode': 200
    }

In your case it seems that you configured the handler to be summarizer_function_lambda.postHandler which means that the handler is in a file named summarizer_function_lambda and the method is named postHandler.

If you want to invoke your function using a URL you have two options: 1. Create an API in API Gateway and set the integration to be the Lambda function. or 2. Create a Lambda function URL. Looking at your template you are using the first option which also creates an API. To find the URL for that API you can either include it in the Outputs section of the template, or go to the CloudFormation console, and check the resources that were created in your stack. API Gateway should be in there.

profile pictureAWS
EXPERT
Uri
answered 2 years ago
profile picture
EXPERT
reviewed 15 days ago
  • Uri,

    This is great for the container and I understand that mapping. However once it is created with AWS SAM with the 'sam deploy' and I have my API gateway and Lambda function created what is my final URL i can send a POST to?? That is what I don't understand what it would be. For example my API endpoint is: https://<my-api>.us-east-2.amazonaws.com/Prod

    So what do I do an example CURL post to? https://<my-api>.us-east-2.amazonaws.com/Prod? Do I need to invoke my actual handler name, in this case postHandler? This is what I mean. I need to understand my final REST API endpoint that I can do a GET or POST to.

  • The URL that is used is not related to the function at all. Lambda functions is just one option for an integration. As you are using SAM you define the trigger in the Events section (see below). In your case you defined that it will be triggered by an API in API Gateway and the path is /postHandler and the method is POST.

    Events:
      SummarizerFunction:
        Type: Api
          Properties:
            Path: /postHandler
            Method: POST
    

    So in your case your function will be invoked by: POST to https://<api-endpoint>/<stage>/postHandler.

    You can export it from your template by adding the Output section like below:

    Outputs:
      MyApi:
        Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/postHandler/"
    

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions