Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the HTTP method in AWS Lambda?

In an AWS Lambda code, how can I get the HTTP method (e.g. GET, POST...) of an HTTP request coming from the AWS Gateway API?

I understand from the documentation that context.httpMethod is the solution for that.

However, I cannot manage to make it work.

For instance, when I try to add the following 3 lines:

    if (context.httpMethod) {
            console.log('HTTP method:', context.httpMethod)
    }

into the AWS sample code of the "microservice-http-endpoint" blueprint as follows:

exports.handler = function(event, context) {

    if (context.httpMethod) {
        console.log('HTTP method:', context.httpMethod)
    }

    console.log('Received event:', JSON.stringify(event, null, 2));

    // For clarity, I have removed the remaining part of the sample
    // provided by AWS, which works well, for instance when triggered 
    // with Postman through the API Gateway as an intermediary.
};

I never have anything in the log because httpMethod is always empty.

like image 260
Xavier M Avatar asked Feb 07 '16 10:02

Xavier M


People also ask

How do you trigger Lambda with HTTP request?

After configuring your function URL, you can invoke your function through its HTTP(S) endpoint via a web browser, curl, Postman, or any HTTP client. To invoke a function URL, you must have lambda:InvokeFunctionUrl permissions. For more information, see Security and auth model.


3 Answers

The context.httpMethod approach works only in templates. So, if you want to have access to the HTTP method in your Lambda function, you need to find the method in the API Gateway (e.g. GET), go to the Integration Request section, click on Mapping Templates, and add a new mapping template for application/json. Then, select the application/json and select Mapping Template and in the edit box enter something like:

{
    "http_method": "$context.httpMethod"
}

Then, when your Lambda function is called, you should see a new attribute in the event passed in called http_method which contains the HTTP method used to invoke the function.

like image 153
garnaat Avatar answered Oct 16 '22 05:10

garnaat


API Gateway now has a built-in mapping template that passes along stuff like http method, route, and a lot more. I can't embed because I don't have enough points, but you get the idea.

Here is a screenshot of how you add it in the API Gateway console:

To get there navigate to AWS Console > API Gateway > (select a resource, IE - GET /home) > Integration Request > Mapping Templates > Then click on application/json and select Method Request Passthrough from dropdown shown in the screenshot above

like image 15
MattS Avatar answered Oct 16 '22 07:10

MattS


I had this problem when I created a template microservice-http-endpoint-python project from functions. Since it creates an HTTP API Gateway, and only REST APIs have Mapping template I was not able to put this work. Only changing the code of Lambda.

Basically, the code does the same, but I am not using the event['httpMethod']

Please check this:

import boto3
import json

print('Loading function')
dynamo = boto3.client('dynamodb')


def respond(err, res=None):
    return {
        'statusCode': '400' if err else '200',
        'body': err.message if err else json.dumps(res),
        'headers': {
            'Content-Type': 'application/json',
        },
    }


def lambda_handler(event, context):
    '''Demonstrates a simple HTTP endpoint using API Gateway. You have full
    access to the request and response payload, including headers and
    status code.

    To scan a DynamoDB table, make a GET request with the TableName as a
    query string parameter. To put, update, or delete an item, make a POST,
    PUT, or DELETE request respectively, passing in the payload to the
    DynamoDB API as a JSON body.
    '''
    print("Received event: " + json.dumps(event, indent=2))

    operations = {
        'DELETE': lambda dynamo, x: dynamo.delete_item(**x),
        'GET': lambda dynamo, x: dynamo.scan(**x),
        'POST': lambda dynamo, x: dynamo.put_item(**x),
        'PUT': lambda dynamo, x: dynamo.update_item(**x),
    }
    
    operation =  event['requestContext']['http']['method']

    if operation in operations:
        payload = event['queryStringParameters'] if operation == 'GET' else json.loads(event['body'])
        return respond(None, operations[operation](dynamo, payload))
    else:
        return respond(ValueError('Unsupported method "{}"'.format(operation)))

I changed the code from:

operation = event['httpMethod']

to

operation = event['requestContext']['http']['method']

How do I get this solution?

I simply returned the entire event, checked the JSON and put it to work with the correct format.

like image 5
Jorge Freitas Avatar answered Oct 16 '22 06:10

Jorge Freitas