Finding the request's URL in a Lambda function - amazon-web-services

I have a Lambda function which is called through an API Gateway using a URL. I need to return a variation of the request's URL by which the Lambda function was originally called in the response. How can I find the URL of the request in a Lambda function?
I was hoping I can pass the URL as a parameter to the Lambda function using API Gateway's mapping template. But I don't see how I can do so!

This body mapping template should give you all you need:
{
"host" : "$input.params('Host')",
"path" : "$context.path"
}
So, for where the url called was 'xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/stage/resource', this will pass an event into Lambda that looks like this:
{
host: 'xxxxxxxxxx.execute-api.us-east-1.amazonaws.com',
path: '/stage/resource'
}

If you are using the Use Lambda Proxy integration you can piece it together from the event properties. This is how I did it in python:
host = event["headers"]["Host"]
path = event["requestContext"]["path"]
proto = event["headers"]["X-Forwarded-Proto"]
request_url = f"{proto}://{host}{path}"

Related

Spring cloud function accessing query parameters

Is it possible to access to query parameters that are forwarded from aws apigateway to awslamdba implemented using spring cloud function. the following is my implementation.
I call this using http get request
example: http://sampledomain.com/test?param1=value
How can I retrieve param1 value in the method below
#Bean
public Function<Message<String>,String> reverseString2() {
return value1 -> {
System.out.println("headers..."+value1.getHeaders());
value1.getHeaders().entrySet().forEach(entry -> System.out.println(entry.getKey() + " - " + entry.getValue()));
return "example";
} ;
}
I don't think the Message supports the Query Parameters. You can try either of the options -
Change your Function to Function<APIGatewayProxyRequestEvent, Message<String>> and then you can access the query parameters using apiGatewayProxyRequestEvent.getQueryStringParameters()
If you want to use Function<Message<String>, Message<String>> , you can change the HttpMethod to POST and send the message in the Request body. Message.getPayload() will provide you with the content.

How to pass a path parameter in API gateway to invoke lambda function?

I need to pass a path param in the API.
By using the mapping template, I am able to pass query params and use them in the function.
Mapping template:
{
"Id": "$input.params('Id')" //this works fine after passing params as <url>?param=vale
}
With reference to this I created the mapping template as following-
{
"Id": "$input.params().querystring.get('Id')" // requirement is to be able to use <url>/value
}
I tried using 'Method request template' under genrate template, but it didn't work either.
When I invoke the URL urlname.execute-api.us-east-2.amazonaws.com/stag/functionname, it gives the value as undefined.
This is how I'm using the param:
class Lambda {
static run(event, context, callback) {
callback(null, 'Id '+ event.Id);
}
}
module.exports = Lambda;
Also, please tell me how to use those params in code.
Be kind :)
In order to be able to use <url>/value and get value from event follow this (Tested):
Configure your API gateway resource
Under /api2/{id} - GET - Integration Request configure your Mapping Templates
Execute request https://123456.execute-api.my-region.amazonaws.com/stage/api2/123
Lambda
console.log(event.id)
callback(null, {
id:event.id
});
CloudWatch
Hope this helps

How do I define URL query parameters in my Body Mapping Template in AWS API Gateway?

My api is of the form:
https://<>.execute-api.us-east-1.amazonaws.com/Testing/api/v1/mobs/<>.json?filename=<>.json&assertion=1
Currently, I have just defined till the .../mobs/<>.json in my Mapping Template, like this:
{
"mob_type": "$input.params('type')"
}
Now, I added query parameters to the url, which are filename and assertion. So, how do I define them in the Body Mapping Template?
This, doesn't work:
{
"mob_type": "$input.params('type')"
"filename": "$input.params('filename')"
"assertion": "$input.params('assertion')"
}
In the Integration Request under "URL Query String Parameters", you need to add a mapping for
method.request.querystring.type
method.request.querystring.filename
method.request.querystring.assertion
http://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html#mapping-request-parameters
With the mapping, they are accessible in the Body Mapping Templates.

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.
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.
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
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.
If event appears an empty object, make sure you enabled proxy integration for the method. Proxy integration for an HTTP method adds request information into event.
See Use Lambda Proxy integration on API Gateway page.
If you are using API gateway, http method will be automatically passed to the event parameter when the lambda is triggered.
export const handler: Handler<APIGatewayProxyEvent> = async (
event: APIGatewayEvent,
context: Context
): Promise<APIGatewayProxyResult> => {
const httpMethod = event.httpMethod;
...
}

Passing path parameters to AWS Lambda

I'm fairly new to AWS. I'm trying to pass a path parameter to my Lambda function like if I do a request:
PUT /users/{identity_id}
and pass in the the body below parameters
{
"name": "shikasta_kashti",
"age": 35
}
then I cannot get event.identity_id in my lambda function. I'm able to access event.name and event.age but not event.identity_id?
I think I would have to do some Mapping Template so I went to my PUT method and in Integration Request -> Mapping Templates added application/json and then selected Mapping Template (instead of Input passthrough) and entered this:
{
"identity_id": "$input.params('identity_id')",
}
but I still cannot get event.identity_id in my Lambda function.
Late response for someone stumbling on this...
The path params are included under event.pathParameters.
Given the request PUT /users/1 you would see a pathParameters object that looks like:
{
"identity_id": 1
}
If you didn't call your function with invoke you'll find the rest of your params in the event.body hash as a string.
To access that you'll do:
const { name, age} = JSON.parse(event.body)