Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

amazon web services - What is the easiest way to integrate aws gateway api with Lambda java function and pass json data between them?

My goal is to build a set of REST apis using aws api gateway, back with java Lambda functions and DynamoDB. The payload of the requests and responses is json. I want to avoid tedious field level mapping code between json and java and between java and dynamodb so am trying to use gson to map json to java objects the enhance dynamodb client so I can use java pojos as inputs and outputs of dynamodb queries. This all works fine when testing the functions stand alone. The issue I am having is passing json between the Gateway and Lambda when trying to integrate gateway apis to the functions. I've tried the two interfaces of Lambda functions, RequestHandler and RequestStreamHandler. I can each of these to do half of what I need, but with RequestHander I have an get runtime errors when returning the response body as json, with RequestStreamHandler I can successfully set the response body as json, but I have problems receiving the request body as json. It seems that something in the aws gateway framework is converting the body json into an escaped string and then another part of the framework is trying to convert the escaped string into json and failing.

What I am trying to do would seem the most basic REST api use case for aws gateway and Lambda, but I can't find any code examples in aws documentation beyond the trivial "hello world" type. Aws documentation seems pretty thin too, so has anyone out there been successfully in building REST apis with json payloads using aws gateway and Lambda who could share the secret of success?

Here's a bit of background as to what I've tried:

API Gateway: I've created gateway apis using Lambda proxy integration to my Lambda functions. I've not specified any models to validate the input. I've just taken the default settings. I am passing a json object as the body of my HTTP requests to test the apis.

Lambda Functions Coded in java using V2 of the SDK.

RequestHandler function - I have created a class the implements the RequestHandler interface specifying the input parameter as a HashMap and output as String. I have successfully got the body of the HTTP request from the hashmap and used Gson to convert the body to my Java pojo. All good. However I fail trying to include json as the body of the response. I've used both Gson and org.json to construct my http response and include json as the body. I can unit test the function successfully, but when integrated with my gateway api I get an error in the gateway (not that the response has been escaped):

Tue Jan 12 11:12:23 UTC 2021 : Endpoint response body before transformations: "{"body":{"message":"hello world"},"isBase64encoded":false,"statusCode":200}" Tue Jan 12 11:06:59 UTC 2021 : Execution failed due to configuration error: Malformed Lambda proxy response

RequestStreamHandler The signature of the handleRequest method is:

public void handleRequest(InputStream input, OutputStream output, Context context)

In this case, I can successfully create a json response using gson and write it to the output stream and the api gateway is fine with it.

However I have a problem with the input. I have tried to use gson to parse the input stream and extract the body. This is fine, but the body is not json, it is an escaped json string, for example:

"{ "id": "10", "title": "Ski trips", "owner": "captain", "locations": [ {"latitude": 55, "longitude":-2 } ] }"

I can't use Gson to parse this nor use Gson to convert it to a pojo. If I try then I get runtime exceptions. To get round this I have used org.apache.commons.text.StringEscapeUtils to remove the escape characters and then removed the leading and trailing quotes round the string. I can then use Gson to convert the resultant string to my pojo class. This is tedious in the extreme.

I've tried changing the classes used for the inputs and outputs of the handleRequest methods, for example to return a JsonObject to see if that changed what I receive but to no avail. If the body contains just a string rather than json, then there is no problem. So just returning "hello world" as the body is fine as per the examples I've found.

I must be missing something, possible in the definition of the gateway api or in the types of the input and output parameters of the Lambda functions but without documentation it really is just wandering around in the dark. Hey all I want to do is to take a json object from the body of a rest request and write it as a json document to a nosql database, getting tripped up by conversion and mapping is really frustrating.

Thanks to anyone who can help me.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Lets say this is our Hander class with ApiGatewayRequest and ApiGatewayProxyResponse are request and response class names.

public class MyHandler implements RequestHandler<ApiGatewayRequest, ApiGatewayProxyResponse> {

    @Override
    public ApiGatewayProxyResponse handleRequest(ApiGatewayRequest request, Context context) {    
 }
}

Request Class

public class ApiGatewayRequest {
    private String body;
    private Map<String, String> headers;
    private Map<String, String> queryStringParameters;
    private Map<String, String> pathParameters;
    private boolean isBase64Encoded;

}

Response Class

public class ApiGatewayProxyResponse {
    private int statusCode;
    private Map<String, String> headers;
    private String body;
}

Json string should be sent in body with com.fasterxml.jackson.databind.ObjectMapper something like

String body = new ObjectMapper().writeValueAsString(ouputObject)

necessary headers ex: Access-Control-Allow-Credentials, Access-Control-Allow-Origin or Content-Type


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...