Reputation: 73
I've set up an API Gateway GET method integrated with a bare-bones AWS Lambda function. I've enabled the Request Body Passthrough on the Integration Request to the pre-set Method request passthrough template.
I would like to do different things based on the resource-path of the request. For example, if the path is /foo, I would interpret the foo request, or /bar would interpret as the bar request, with the same Lambda function. So I need to switch based on the resource-path within the Lambda function itself.
I'm getting stuck accessing the mapped payload template. All the data should be there according to the AWS help. But in java, I can't figure out how to convert the input from API gateway into parsable json using Jackson, org.json, or json-path.
Here is my Lambda code. Any help on how to get "resource-path", or any of the method request passthrough, from the API Gateway GET would be appreciated.
import org.json.JSONObject;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class LambdaFunctionHandler implements RequestHandler<Object, Object> {
@Override
public Object handleRequest(Object input, Context context) {
JSONObject inputJson = new JSONObject(input.toString());
JSONObject contextJson = inputJson.getJSONObject("context");
String resourcePath = contextJson.getString("resource-path");
return resourcePath;
}
}
And here is what I believe is being sent into the function as input:
{
"body-json" : {},
"params" : {
"path" : {},
"querystring" : {},
"header" : {}
},
"stage-variables" : {},
"context" : {
"account-id" : "xxxxxxxxx",
"api-id" : "xxxxxxxxx",
"api-key" : "xxxxxxxxx",
"authorizer-principal-id" : "",
"caller" : "xxxxxxxxx",
"cognito-authentication-provider" : "",
"cognito-authentication-type" : "",
"cognito-identity-id" : "",
"cognito-identity-pool-id" : "",
"http-method" : "GET",
"stage" : "test-invoke-stage",
"source-ip" : "test-invoke-source-ip",
"user" : "xxxxxxxxxxxxxxxx",
"user-agent" : "Apache-HttpClient/4.5.x (Java/1.8.0_112)",
"user-arn" : "arn:aws:iam::230537478972:root",
"request-id" : "test-invoke-request",
"resource-id" : "75bakm",
"resource-path" : "/text"
}
}
But I'm getting:
{
"errorMessage": "Expected a ':' after a key at 11 [character 12 line 1]",
"errorType": "org.json.JSONException",
"stackTrace": [
"org.json.JSONTokener.syntaxError(JSONTokener.java:433)",
"org.json.JSONObject.<init>(JSONObject.java:216)",
"org.json.JSONObject.<init>(JSONObject.java:323)",
"xxx.LambdaFunctionHandler.handleRequest(LambdaFunctionHandler.java:12)"
]
}
Upvotes: 3
Views: 3677
Reputation: 73
Thanks to Ka Hou leong for the direction, I've solved with the following:
1) Added dependency in Maven for aws-serverless-java-container
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-core</artifactId>
<version>0.4</version>
</dependency>
2) Modified my LambdaFunctionHandler class to use AwsProxyRequest and AwsProxyResponse:
import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.internal.model.AwsProxyResponse;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class LambdaFunctionHandler implements RequestHandler<AwsProxyRequest, Object> {
public Object handleRequest(AwsProxyRequest input, Context context) {
AwsProxyResponse response = new AwsProxyResponse();
String resourcePath = input.getRequestContext().getResourcePath();
response.setStatusCode(200);
response.setBody(resourcePath);
return response;
}
}
3) Modified my API Gateway method Integration Request settings to Use Lambda Proxy Integration.
From here I have access to everything in the input object as an AwsProxyRequest, and will manipulate response as an AwsProxyResponse with anything I want to respond with.
Upvotes: 4
Reputation: 6515
You can write your own POJO to match the request from API Gateway, then you will be able to access the resource path from a getter.
POJOs example:
public class LambdaFunctionHandler implements RequestHandler<Object, Object> {
@Override
public Object handleRequest(AwsProxyRequest input, Context context) {
String resourcePath = input.getRequestContext().getResourcePath();
return resourcePath;
}
}
public class AwsProxyRequest {
//-------------------------------------------------------------
// Variables - Private
//-------------------------------------------------------------
private ApiGatewayRequestContext requestContext;
....
//-------------------------------------------------------------
// Methods - Getter/Setter
//-------------------------------------------------------------
public ApiGatewayRequestContext getRequestContext() {
return requestContext;
}
public void setRequestContext(ApiGatewayRequestContext requestContext) {
this.requestContext = requestContext;
}
....
}
public class ApiGatewayRequestContext {
//-------------------------------------------------------------
// Variables - Private
//-------------------------------------------------------------
private String resourcePath;
...
//-------------------------------------------------------------
// Methods - Getter/Setter
//-------------------------------------------------------------
public String getResourcePath() {
return resourcePath;
}
public void setResourcePath(String resourcePath) {
this.resourcePath = resourcePath;
}
....
}
If you want the full proxy request POJO, you can find them from here.
Upvotes: 1