Spring cloud function accessing query parameters - spring-cloud-function

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.

Related

How to pass event info from aws API Gateway get to Lambda?

How do I refer to API Gateway GET query string parameters in a Lambda function ?
When I test I can use my local test event with "username": "larry"
When I test with a post I can use the body parameters as the event with "username": "larry"
With a get request, I don't have a body. How could I use query string parameters and then refer to them in the request. What event or other attribute do I use to get at the query param or what setting or change do I need to make?
Method request
Integration request
Query String
When testing I've referred to event["username", what do I do for an API request passing it as a query string parameter?
Login and click to API gateway and click on method - GET method
Go to Method Execution - select URL Query String Parameter and add query String parameter username
Now go to Integration Request tab Choose Body Mapping Template,
"content type application/json"
Generate Template like below
{
"username": "$input.params('username')"
}
Now write ;ambda which accept key value in pair .
module.exports.get = (event, context, callback) => {
const { username } = event.pathParameters;
console.log("username", username);
}
Now go and deploy your api on apigetway and find url and hit in browser example
https://xxx.yyy-api.us-east-2.amazonaws.com/prod/username?vaquarkhan
Hope it will help
https://docs.aws.amazon.com/de_de/apigateway/latest/developerguide/welcome.html
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on-proxy-resource

How do I map path parameters from an API Gateway API to the Request Object of a Java Lambda

I have a lambda, written in Java, that accepts a Request Object of the structure
{
"id": "be1c320a-144f-464d-b32c-38ec7fb4445b",
"userId": "foobar"
}
When I call this Lambda through the test interface with such an object, it works fine.
I want to create an API where a GET request to
/users/foobar/items/be1c320a-144f-464d-b32c-38ec7fb4445b
i.e. of the form
/users/{userId}/items/{id}
calls this Lambda.
I have created the API resources /users, {userId}, items, and {id} appropriately.
And I have created the GET method (on /users/{userId}/items/{id})and associated it to the lambda.
When I test the API, it invokes the lambda, but with null values in the request. I can see it package the path as {"id":"be1c320a-144f-464d-b32c-38ec7fb4445b","userId": "foobar"} in the logs, but that's not being sent in the body.
I have tried creating a template map (and have tried RTFM), but cannot see how to map path parameters to a body.
How do I achieve this mapping?
I think your Request Object structure may not be properly configured. There may be a few ways to configure this. Here is some information that has helped me.
How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway - Demonstrates this mapping (albeit with python). However, taking the top response, if you enable "Use Lambda Proxy integration", you can similarily do this with Java as so:
#Override
public Object handleRequest(APIGatewayProxyRequestEvent input, Context context) {
Map<String, String> pathParameters = input.getPathParameters();
String id = pathParameters.get("id");
String userId = pathParameters.get("userId");
// Handle rest of request..
}
This is a tuturial using the serverless framework to create an Api with Java. This tutorial similarily accesses the pathParameters by parsing the input rather than using the APIGatewayProxyRequestEvent java class.
#Override
public Object handleRequest(Map<String, Object> input, Context context) {
try {
// get the 'pathParameters' from input
Map<String,String> pathParameters = (Map<String,String>)input.get("pathParameters");
String id = pathParameters.get("id");
String userId = pathParameters.get("userId");
} catch (Exception ex) {
logger.error("Error in retrieving product: " + ex);
}
}
Use a mapping template.
First, in the Method Request section, you should see userId and id as Request Paths
Then, in the Integration Request, do not choose Proxy Integration.
Then in the Mapping Templates section, add a new mapping template for application/json of the form
{
"id" : "$method.request.path.id",
"userId" : "$method.request.path.user_id"
}

Finding the request's URL in a Lambda function

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}"

Unable to access query string params inside AWS Api Gateway

I have configured a resource with a GET method on AWS API Gateway. Integration type is configured as HTTP, but it seems that I cannot access Url Query string parameters without Lambda Functions.
For example
I have api endpoint https://api.domain.com/v1/object/500?param_id=305 and I would like to integrate it with an existing http such as http://somedomain.com/object/500?param_id=305
When I define endpoint URL such as http://somedomain.com/object/{id}?param_id={param_id} I am not able to define param_id as url query string parameter
I am getting a following error:
Invalid mapping expression specified: Validation Result: warnings : [], errors : [Invalid mapping expression parameter specified: method.request.querystring.param_id
How can I access query string params without using Lambda functions?
You can use body mapping template in the integration request section and get request body and query strings. Construct a new JSON at body mapping template, which will have data from request body and query string. As we are adding body mapping template your business logic will get the JSON we have constructed at body mapping template.
Inside body mapping template to get query string please do ,
$input.params('querystringkey')
For example inside body mapping template,
#set($inputRoot = $input.path('$'))
{
"firstName" : "$input.path('$.firstName')", //This is to get path variable
"lastName" : "$input.path('$.lastName')"
"language" : "$input.params('$.language')" //This is to get query string
}
Please read https://aws.amazon.com/blogs/compute/tag/mapping-templates/ for more details on body mapping template

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)