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)?