URL: /test/{userName}
In AWS Lambda function, How can I get the {username} path parameter value.
I am calling lambda function through AWS API gaetway.
If you are using AWS integration type:
Use a mapping template to send $input.params('username') property in the request body to your Lambda function.
If you are using AWS_PROXY integration type:
You can access the path parameters via the "pathParameters" property of the incoming event.
Related
Just started with using AWS Lambda's. I'm writing my functions in Java. I'd like to know if you can pass parameters to an AWS Lambda through the API Gateway? My lambda function basically makes a call to a webservice which returns JSON, create's POJO's from the JSON and then a CSV file which I upload to S3. Now this webservice you could pass productId if you wanted to, if you don't it just returns all products.
This would return the product with id of 123456
www.likssmark.com/test/api/getOrders?productId=123456
This would return all orders as JSON payload:
www.likssmark.com/test/api/getOrders
How do I pass productId into my java lambda? The lambda is triggered via cloud watch on a schedule - I've been testing it using Postman.
Hope this makes sense?
Many thanks for any advice.
If you only need to use Cloudwatch, just pass a JSON string to your Lambda:
In your Lambda you can then pull out the data:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
...
public class ProductIdLambda implements RequestStreamHandler {
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
LambdaLogger logger = context.getLogger();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(inputStream);
String productId = rootNode.path("productId").asInt();
This pulls the productId out of the InputStream.
If you need both CloudWatch events and API Gateway integration you can either have two different Lambda's or, to the suggestion #f7o made, introspect the incoming stream for an API Gateway call. You could have something like:
String httpMethod = rootNode.path("httpMethod").asText();
if( httpMethod != null ) // then we were called by API Gateway
The input from API Gateway will include an optional parameter in the input JSON:
"queryStringParameters": {
"productId": "12345"
},
that you can then get your productId from.
You can use AWS API-Gateway to pass parameters to your AWS lambda service.
This AWS documentation describes it: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
In my German blog I wrote an article about how to implement an AWS lambda service with Java and Spring Boot. Here I am also passing parameters over API Gateway to AWS lambda service:
https://agile-coding.blogspot.com/2020/09/aws-lambda-services-mit-spring-boot.html
There are multiple ways to integrate lambda within an API gateway. For starters I would create a simple HTTP API with either a default route or a specific route. Attach a lambda integration to the route.
This should proxy the http request to your lambda function. You lambda handler will receive an event which contains information about the request as path, cookies, ... and also your query parameters. See the documentation for details on the passes json (https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html).
To determine who is actually calling the function (cloudwatch, api gateway) just test the content of the event for some fields before parsing/reading it to make sure you respond appropriate.
In API Gateway I have a GET endpoint like following (with some request headers too)
http://awesomedomain/v1/myspecialkey/find?a=b
Is there a way the Lambda (Authorizer) code can read "myspecialkey"?
Thanks in advance
Yes it is possible, when you are building lambda authorizer you can choose Lambda Payload Type to be Request.
Assuming that you have named your first lambda parameter events, then inside of the lambda, you will have access to your parameter values via
event.pathParameters
as well as access to your query string via
event.queryStringParameters
And other request information if needed, such as authorization token which you can extract from event.headers.
the above code uses NodeJs syntax, the same logic holds true for Java but you will need to modify it according to Java syntax
In Velocity template engine I could just use a model variable
$request
which is a instance of HttpServletRequest. How to get a http request object in Freemarker template engine? According to the freemarker documentation,
http://freemarker.org/docs/api/freemarker/ext/servlet/HttpRequestHashModel.html#getRequest--
there is a class HttpRequestHashModel and its method returns a instance of HttpServletRequest.
So the question is, how to access this object in spring boot? I found some information about using a
${Request}
variable, but I got an error that it returns a null/missing object.
As far as I know, Spring does not expose the request directly to the template, however by default it does expose the model attribute springMacroRequestContext, which contains a lot of information about the request.
The springMacroRequestContext variable allows you to fetch information about the request.
For instance:
<html lang="${springMacroRequestContext.locale.language}" class="no-js">
or
${springMacroRequestContext.contextPath}
With your requirement of getting the path:
${springMacroRequestContext.requestUri}
should probably be sufficient.
See the org.springframework.web.servlet.support.RequestContext for all the available methods.
You can change the name of this attribute by setting the following property in your application.properties:
spring.freemarker.request-context-attribute=rc
This allows you to shorten the syntax in your template:
${rc.locale}
I have a basic service in Java, for example:
public interface FolderService {
void deleteFolder(String path);
void createFolder(String path, String folderName);
void moveFolder(String oldPath, String newPath);
}
which has multiple implementations. How can I map this service on AWS Lambda and API Gateway ?
I am expecting the API to have the format
POST {some_url}/folderService/createFolder
or
GET {some_url}/folderService/createFolder?path=/home/user&folderName=test
First, design your API mapping each HTTP method to a Java method.
DELETE /{path}
POST /{path}/{folderName}
PUT /{oldPath}?to={newPath} or PUT /{newPath}?from={oldPath}
Second, create the API Gateway Mapping. Each HTTP method has its own mapping. Define a constant value with the name of the method. Ex.
"action" : "deleteFolder"
Create three lambda functions. Each function, in the function handler, reads the "action" attribute and call the correct method.
or
Create one single lambda function that reads the action and calls the respective Java method.
API Gateway Mapping Template
Lambda Function Handler (Java)
You already have experience with AWS Lambda? The mapping part can be tricky. Feel free to ask for more details.
Is it possible from varnish vcl script to set an attribute on the request and get it in the backend by java Servlet getAttribute() method? http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getAttribute(java.lang.String)
Request attributes are a mechanism internal to the Servlet framework, so it is not possible to set them from the outside. It would however be possible to set a Request parameter (in either query String or request body, depending on the request type), that would then be available through HttpServletRequest.getParameter(name)