You can use various patterns for Java Lambda input / output types.
In the official documentation, it is written here [https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/java-handler.html#java-handler-types).
Map Edition introduced how to handle JSON using Map type.
If you look at the Map method code, you will see many casts from Object type to String / Integer / Long type and so on.
public class MapFunction implements RequestHandler<Map<String, Object>, Map<String, Object>> {
@Override
public Map<String, Object> handleRequest(Map<String, Object> event, Context context) {
String name = (String) event.get("name");
System.out.println(name); // orange juice
Integer price = (Integer) event.get("price");
System.out.println(price); // 1000
Long releaseDate = (Long) event.get("releaseDate");
System.out.println(releaseDate); // 1601606387939
...
Not only is the code dirty, but it may not get caught at compile time if the type changes, and you may get a ClassCastException at run time.
Therefore, it is the POJO method.
First, create a POJO class that will replace Map. The Size class is an inner class, but it can be a normal class.
import java.util.List;
public class Product {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private Integer price;
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
private Long releaseDate;
public Long getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(Long releaseDate) {
this.releaseDate = releaseDate;
}
private Double rate;
public Double getRate() {
return rate;
}
public void setRate(Double rate) {
this.rate = rate;
}
private List<String> rawMaterial;
public List<String> getRawMaterial() {
return rawMaterial;
}
public void setRawMaterial(List<String> rawMaterial) {
this.rawMaterial = rawMaterial;
}
private Size size;
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
public static class Size {
private Integer height;
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
private Integer width;
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
private Integer depth;
public Integer getDepth() {
return depth;
}
public void setDepth(Integer depth) {
this.depth = depth;
}
}
}
The handler for your Lambda function uses this class as the I / O type.
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Arrays;
import java.util.List;
public class PojoFunction implements RequestHandler<Product, Product> {
@Override
public Product handleRequest(Product product, Context context) {
String name = product.getName();
System.out.println(name); // orange juice
Integer price = product.getPrice();
System.out.println(price); // 1000
Long releaseDate = product.getReleaseDate();
System.out.println(releaseDate); // 1601606387939
Double rate = product.getRate();
System.out.println(rate); // 4.5
List<String> rawMaterial = product.getRawMaterial();
System.out.println(rawMaterial); // [orange, fragrance]
Product.Size size = product.getSize();
Integer height = size.getHeight();
System.out.println(height); // 10
Integer width = size.getWidth();
System.out.println(width); // 20
Integer depth = size.getDepth();
System.out.println(depth); // 30
Product response = new Product();
response.setName("coffee");
response.setPrice(Integer.valueOf(500));
response.setReleaseDate(System.currentTimeMillis());
response.setRate(Double.valueOf(4.2));
response.setRawMaterial(Arrays.asList("coffee", "sugar"));
Product.Size responseSize = new Product.Size();
responseSize.setHeight(Integer.valueOf(100));
responseSize.setWidth(Integer.valueOf(200));
responseSize.setDepth(Integer.valueOf(300));
response.setSize(responseSize);
return response;
}
}
The cast has disappeared cleanly. Now you can get a compile error even if you change the type.
If you do this by passing the following JSON,
{
"name": "orange juice",
"price": 1000,
"releaseDate": 1601606387939,
"rate": 4.5,
"rawMaterial": ["orange", "fragrance"],
"size": {
"height": 10,
"width": 20,
"depth": 30
}
}
The output will be like this.
{
"name": "coffee",
"price": 500,
"releaseDate": 1601623033115,
"rate": 4.2,
"rawMaterial": [
"coffee",
"sugar"
],
"size": {
"height": 100,
"width": 200,
"depth": 300
}
}
The POJO method seems to maintain the order, unlike the Map method HashMap.
AWS officially provides a convenient library, aws-lambda-java-libs, that takes advantage of the ability to map JSON to POJO classes. https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-events
For example, in the case of Lambda proxy integration of API Gateway, you can use the POJO class provided like this for input and output.
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
response.setStatusCode(Integer.valueOf(200));
response.setBody("ok");
return response;
}
Next, I would like to introduce the InputStream / OutputStream method.
I tried Java Lambda input / output type ~ Stream version ~ https://qiita.com/kazfuku/items/6f0f55ffa3a88d76cfaa
Recommended Posts