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.
Related
There are many similar threads out there, so I'll try to be simple and specific.
My API Gateway has GET method, without "Use Lambda Proxy integration" check marked. (Yes, to make my life little bit more difficult)
My assumption is that I have API Gateway portion working correctly, with query string parameters.
It has been deployed through Deploy API button
I also have mapping template written, as exactly said by this instruction provided by AWS.
Now, in java, I have the following:
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
The concern is that event object is empty. Have I not been using the correct request event object?
ADDITIONAL NOTE
Per request, here's my lambda function below:
LambdaLogger logger = context.getLogger();
logger.log("EVENT: " + gson.toJson(event));
And here's what CloudWatch prints:
EVENT: {}
Did you configured this under GET - > Method Request?
After doublechecking, did you press the deploy button ?
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
I'm trying to create a visualisation of REST calls among several internal and external services/servers. I'd like to know which endpoint called which other endpoint. I figured that the only way to do this is to do this on the caller side, because the receiver does not have any information about the caller endpoint.
Here's my thinking:
I create an object like RestTemplate and call the method.
I create an Interceptor or something like that, which will extract the information from the RestTemplate.
My problem is that I'm not sure how to find out which REST endpoint called the RestTemplate method. The RestTemplate (or other similar object) call could be called in nested methods, so for example the endpoint could invoke a private method, which then calls the external service itself.
Is there any way how to get this information? Or am I maybe just thinking too hard and there is an easier way to do this?
Example:
#GetMapping("/hello")
public String hello() {
methodThatCallsOtherEndpoint("something.com/weather"); // this method inside itself calls an endpoint
logRestCall("localhost:8000/hello", "something.com/weather"); // how do I do this automatically without having to type it myself?
return "hello";
}
Thanks for any help.
If these services/servers have a static IP you can possibly, tag them by their IP address?
You can use Spring Sleuth to trace the relationship between different REST calls.
How do I access the request object inside my java controller in the play framework?
The Scala tutorial-page references some sort of "request" object, but I don't see how to access that in the Java tutorial-page.
I'm using Play Framework 2.5
The answer is really clear and straightforward:
When you call request() you access to the requests object, like headers and body, example request().body()
Much more here: https://www.playframework.com/documentation/2.5.x/JavaBodyParsers
Just add explicitly type: Action { request: Request[_] => ... }