I tried Java Lambda input / output type ~ POJO edition ~

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.

Convenient library

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;
}

at the end

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

I tried Java Lambda input / output type ~ POJO edition ~
I tried the input / output type of Java Lambda ~ Map edition ~
I tried Java Lambda input / output type ~ Stream version ~
I tried to summarize Java lambda expressions
I tried to output multiplication table in Java
paiza skill check standard input / output summary [Java edition]
I tried Drools (Java, InputStream)
I tried using Java REPL
I tried metaprogramming in Java
Object-oriented child !? I tried Deep Learning in Java (trial edition)
I tried to convert a string to a LocalDate type in Java
[Java] I want to test standard input & standard output with JUnit
I tried to interact with Java
I tried UDP communication with Java
I tried the Java framework "Quarkus"
I tried using Java8 Stream API
I tried using JWT in Java
I tried to summarize Java learning (1)
I tried to summarize Java 8 now
I tried using Java memo LocalDate
I tried using GoogleHttpClient of Java
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (PowerMockito edition)
I tried using Elasticsearch API in Java
I tried Cassandra's Object Mapper for Java
Java9 was included, so I tried jshell.
I tried the new era in Java
I tried using OpenCV with Java + Tomcat
I tried Google's entrance exam (unofficial) [java]
I can't remember the text file input / output in Java, so I summarized it.
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (black magic edition)
Let's write Java file input / output with NIO
I tried putting Java on my Mac easily
I tried to make Basic authentication with Java
[Java] How to get and output standard input
java I tried to break a simple block
I tried hitting a Java method from ABCL
I tried to implement deep learning in Java
Effective Java 3rd Edition Chapter 7 Lambda and Streams
I tried to create Alexa skill in Java
I tried to break a block with java (1)
I tried running Java on a Mac terminal
I tried to explain Effective Java 3rd edition "almost all chapters" in "easy-to-read Japanese".