For my POC, created simple lambda function , which will give emp information through rest api.
Created lambda function and access all the emp data using API gateway.
Facing some challenges while accessing particular data.
i am looking for
emp/1 - to retrieve emp id
emp/_search?name="apple" - search name contains apple.
Question is how to retrieve path and request parameters in java code.
public class TestAwsLambdaFunction implements RequestHandler<Map<String, Object>, String> {
#Override
public String handleRequest(Map<String, Object> input, Context context) {
String empID= null;
try {
#SuppressWarnings("unchecked")
Map<String, String> pathParameters = (Map<String, String>) input.get("querystring");
empID= pathParameters.get("id");
System.out.println(empID);
// TO-Do Business logic -
} catch (Exception e) {
// TODO: handle exception
}
return "Hello from Lambda!" + empID;
}
}
What is the best way to expose my data in Rest api call. Bit confused with Lambda or serverless .
have any option to show the data via page wise. Since i am new to AWS. Please guide me
Question is how to retrieve path and request parameters in java code.
You can use mapping template to send $input.params('name') property in the request body to your Lambda function.
What is the best way to expose my data in Rest api call
Use the proxy integration with these guidelines:
Avoid greedy path variables, except perhaps for a catch-all 404.
Avoid using the ANY method.
Define request models and enable request validation (remember it’s off by default).
In your Lambda, check that the content-type header matches one of your request models, and return a 415 Unsupported Media Type status code if it doesn’t (the proxy integration uses the WHEN_NO_MATCH passthrough behavior). After this check, your Lambda can assume the request validation is fully enforced.
By Ben Kehoe
https://read.acloud.guru/how-you-should-and-should-not-use-the-api-gateway-proxy-integration-f9e35479b993
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html#api-gateway-proxy-integration-lambda-function-java
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-call-api.html
https://github.com/vaquarkhan/Serverless-AWS-Lambda-guide/blob/master/01-aws-lambda-serverless-framework/02-building-rest-api-in-nodejs-with-lambda-gateway.md
https://www.puresec.io/blog/aws-security-best-practices-for-api-gateway
https://www.stackery.io/blog/serverless-function-architecture-principles/
https://technology.finra.org/code/enjoying-auto-scaling-integrated-authentication-low-host-cost.html
You need to choose Lambda Proxy Integrations when you set up your API Gateway. Here's official document Set up Lambda Proxy Integrations in API Gateway.
In this case, API Gateway will pass the whole request data to Lambda, including the request headers, query string parameters, URL path variables and so on. Then you can parse the data using your Java code.
Related
I am learning AWS API Gateway with Lambda non-proxy integration. I have a few questions?
1) Can I use APIGatewayProxyRequestEvent as the input event for Lambda non-proxy integration?
2) Let's say I have a Class 'SomeBean' with just one property 'name' which I want to sent in post body. How can I specify the mapping template to map the JSON object from the post body to 'body' property of APIGatewayProxyRequestEvent. I tried the following and nothing seems working.
{"body": $input.body}, {"body" : $input.json('$')}, {"body" : $input.path('$')}
3) Also what should be the format of the request payload ? I tried {"name":"myName"}
Any help will be greatly appreciated. Thanks in advane.
If you need to access the headers and body of the request, then use API Gateway Lambda Proxy Integration. This will encapsulate the request to an event object which you use to access all the information of the request.
For e.g. if you are using Java, then use the following Lambda handler.
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent>{
....
#Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent request, Context context) {
This is similar to this post API-Gateway Integration Request HTTP Header not mapping query string to header but I can't see any answer for it and all of the answers are not related to what the question is intended.
I am trying to add the integration request parameters in API Gateway, but whenever I set 'Http Headers' as shown here and 'Mapping template' as passthrough, I could not see that header when I log inside the lambda.
Also in the integration response I cannot reference it inside the integration header response parameters. The "integration.response.header.cokers" will be returned blank when I invoke the API. This is how I configured the integration response
Ultimately the solution here is to implement a lambda proxy integration.
A proxy integration in API Gateway tells API Gateway to simply forward all headers to the integration for processing, which means you will see all of those values in your lambda function.
NOTE: Lambda has to return a specific response format back to API Gateway if it's a proxy integration. Ultimately, the response should be something like:
{
'statusCode': 200,
'headers': {
'echo-proxy': True
},
'body': 'some payload'
}
What you are trying to do right now is map everything manually, which is a deprecated approach and usually you don't want to do that unless you absolutely have to because it's kind of a pain.
If you have to map the headers manually start by mapping them in the the method request so it can carry on to the next step and so on. Basically like this:
Method Request -> Maps variable to Integration Request -> Maps variable to Body Mapping Template -> Maps variable to actual request header
What you have in your screenshot for the Integration Request -> HTTP Headers is:
Name: cokers
Mapped from: 'blah'
However, "mapped from" should look something like "method.request.header.coker" which is a standardized path (meaning to get the value from the Method Request Header field with name "coker").
Once you have added the coker header to the Method Request, and the Integration Request HTTP Headers are mapped correctly, you have to implement a mapping template. Set the content-type to application/json with passthrough set to "When there are no templates defined(recommended)" and a simple mapping template:
{
"headers": {
"coker" : "$input.params('coker')"
}
}
That is the way my API is setup and it returns the following to me because I had my lambda function return the event as a json object back to API GW:
{"body": "{\"headers\": {\"coker\": \"mapped\"}}", "statusCode": 200}
NOTE: the value of my header "coker" in the request on the client side is "mapped"
UPDATED ANSWER
To map the original "coker" header to "coker2" (or any other name you want to give it) you simply set the name of the header in your mapping template like so:
{
"headers": {
"coker2" : "$input.params('coker')"
}
}
Then edit your lambda function to return "coker2" header and you should get a response like this:
{"body": "{\"headers\": {\"coker2\": \"mapped\"}}", "statusCode": 200}
My requirement is I will expose the ESB integration implementation as a REST API.
1) In the implementation part whenever they will call This ESB API it has to route based on content in the post request sent to ESB(this can be achieved by content based routing pattern ).
2) But on the Endpoint side Which is to be called by the ESB while routing based on content may vary means, if today there is 2 end point to call tomorrow it may rise to 5 like that how to apply changes are is there any solution. So, how to achieve this dynamic integration.
I have 4 ways to achieve this integration pattern.
1) Deploy files in the registry which has the endpoint in it and having the file name which is same as the content name(regex) sent in the payload for routing. Then by storing that name in property mediator and use concat function to read that file in another property mediator, and by pattern matching read the endpoint. Thus you can use that endpoint and achieve the dynamic content based routing.
2) Have separate sequence each one to call one endpoint and have the same name as the content name. The main sequence will call the sequence based on the content.
3)Store the content on which to be routed and endpoint in the RDBMS database then use DB lookup mediator to retrieve the endpoint based on this you can route.
4) I think this is best and suitable for integration scenario where tomorrow the endpoint may change( that is when the number of the endpoint is not fixed ) and each endpoint wants a different transformation of the payload(I mean XML to json or JSON to XML etc..).
First, use one API and store the content in property mediator and use that mediator to call another API which has the implementation to call the endpoint.
For example, if the content based on which routing has to happen has the payload like this
{ "content":"c1" }
Store the content in property mediator using name uri.var.address. Then create another API's which will have the implementation to call endpoint(For each endpoint create separate API's) and URI-Template of the API's should have content stored in the property mediator(same as payload request). While using send mediator to call these ENDPOINT implemented API's use http request having url of the API with /{uri.var.address} because to match the URI-template details.
I want to use API Gateway as a caching proxy for an HTTP server, which in turn uses jsonapi-resources to define the API.
The issue is that jsonapi-resources requires query string parameters of the form ?page[number]=10&page[size]=10 to paginate results. However, if I try to add page[number] to URL Query String Parameters on a Method Request page, I receive the following error:
I've also tried to percent-encode the name as page%5Bnumber%5D without any success; the parameter is still filtered out.
Is there a way to make it work?
If you encode the [ by %5B, API Gateway doesn't allow % in the parameter name.
Currently, AWS API Gateway only supports the parameter name matches ^[a-zA-Z0-9._$-]+$
Does page.number work for you?
I'm using WSO2 API Manager and I want access to details of the client's incoming API request (into API Manager, for example, the HTTP method) as well the response from my API endpoint. I've followed the approach in the following document to write a custom mediator class which gets invokes on both the "In" (for the request) and "Out" (for the response) flows:
https://docs.wso2.org/display/AM160/Adding+a+Mediation+Extension
It seems I can get various bits of data that I need from the MessageContext that is passed into my mediator, but I'm struggling with getting the response code from my API endpoint. Is there a way to get access to the HTTP response itself (and all it's headers and other elements) from the MessageContext? I stumbled across the PassThroughTransportUtils class which has a determineHttpStatusCode method which I could call but I'm not sure this is the best way of doing it.
"HTTP_SC" property is stored in Axis2MessageContext, which can be accessed as below:
org.apache.axis2.context.MessageContext msgContext = ((Axis2MessageContext) messageContext).getAxis2MessageContext();
String httpStatusCode = (String) msgContext.getProperty(NhttpConstants.HTTP_SC);
can be null, if not set.