aws / aws-lambda-java-libs

Official mirror for interface definitions and helper classes for Java code running on the AWS Lambda platform.

Home Page:https://aws.amazon.com/lambda/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lambda input parameter deserialisation using Lombok doesn't work for @Jacksonized @Builder

johannesfloriangeiger opened this issue · comments

Working with Java Lambdas I encountered the situation that @Jacksonized @Builder parameter POJO do not work.

Example:

package org.example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Builder;
import lombok.Data;
import lombok.extern.jackson.Jacksonized;

public class StringHandler implements RequestHandler<String, String> {

    @Data
    @Builder
    @Jacksonized
    public static class Parameter {

        @Data
        @Builder
        @Jacksonized
        public static final class Input {

            private final String value;
        }

        private final Input input;
    }

    @Override
    public String handleRequest(final String event, final Context context) {
        final var objectMapper = new ObjectMapper();

        try {
            final var parameter = objectMapper.readValue(event, Parameter.class);

            return parameter.input.value;
        } catch (final JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

works with input

"{ \"input\": { \"value\": \"StringInput\" } }"

but is ugly because of the stringified JSON input and

package org.example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import lombok.Data;

public class NoArgInputHandler implements RequestHandler<NoArgInputHandler.Parameter, String> {

    @Data
    public static class Parameter {

        @Data
        public static final class Input {

            private String value;
        }

        private Input input;
    }

    @Override
    public String handleRequest(final NoArgInputHandler.Parameter parameter, final Context context) {
        return parameter.input.value;
    }
}

works with input

{
  "input": {
      "value": "NoArgInput"
  }
}

but is also not optimal because the Parameter class has a no arg constructor even though it's technically not necessary and

package org.example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import lombok.Data;

public class DataInputHandler implements RequestHandler<DataInputHandler.Parameter, String> {

    @Data
    public static class Parameter {

        @Data
        public static final class Input {

            private final String value;
        }

        private final Input input;
    }

    @Override
    public String handleRequest(final DataInputHandler.Parameter parameter, final Context context) {
        return parameter.input.value;
    }
}

does not work with input

{
  "input": {
      "value": "DataInput"
  }
}

because of the missing constructor and

package org.example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import lombok.Builder;
import lombok.Data;
import lombok.extern.jackson.Jacksonized;

public class JacksonizedInputHandler implements RequestHandler<JacksonizedInputHandler.Parameter, String> {

    @Data
    @Builder
    @Jacksonized
    public static class Parameter {

        @Data
        @Builder
        @Jacksonized
        public static final class Input {

            private final String value;
        }

        private final Input input;
    }

    @Override
    public String handleRequest(final JacksonizedInputHandler.Parameter parameter, final Context context) {
        return parameter.input.value;
    }
}

also doesn't work with input

{
  "input": {
      "value": "JacksonizedInput"
  }
}

although it is properly annotated but it would be the cleanest solution as the Parameter class doesn't need a no arg constructor.

Any chance of getting a similar behaviour to default Jackson implemented (first example)?