I am trying to use Java + Dagger to create a few basic lambdas to handle API Gateway requests.
I am trying to use Dagger to inject the AWS clients the different functions will need, but am struggling to get the actual lambda invocations to call the default constructor.
I have
@Singleton
@Component(modules = {HandlerCommonModule.class})
public interface LambdaHandlers {
CreateRecord createRecord();
DeleteRecord DeleteRecord();
}
and
@Module
public class HandlerCommonModule {
@Provides
@Singleton
public static DynamoDbClient dynamoDbClient() {
return DynamoDbClient.builder().build();
}
}
and then one of the handler classes looks like
public class CreateRecord extends BaseHandler {
private static final Logger log = LogManager.getLogger(CreateRecord.class);
@NonNull
DynamoDbClient dynamoDbClient;
@Inject
public CreateRecord(final DynamoDbClient dynamoDbClient) {
this.dynamoDbClient = dynamoDbClient;
}
@Override
public BaseResponse process(BaseRequest request, Context context) {
log.info("...");
}
}
which is extending a base handler that I hope to eventually have unwrap the API Gateway request, and pass a request specific shape to the handler (CreateRecordRequest, and DeleteRecordRequest accordingly)
public abstract class BaseHandler implements RequestHandler<BaseRequest, BaseResponse> {
private static final Logger LOGGER = LogManager.getLogger(BaseHandler.class);
protected abstract BaseResponse process(BaseRequest request, Context context);
@Override
public final BaseResponse handleRequest(BaseRequest request, Context context) {
try {
return process(request, context);
} catch (Exception e) {
LOGGER.debug("Exception: {e}", e);
}
return defaultErrorResponse();
}
protected BaseResponse defaultErrorResponse() {
return BaseResponse.builder()
.statusCode(503)
.body("Service unavailable. Try again later.")
.build();
}
}
Lambda is claiming there is no no-arg constructer for the classes, which is true. Looking at the class builds I see that Dagger creates on in LambdaHandlers, but I am not sure how I can use this or what needs to change to create default constructors the aws lambdas can use. All of the examples I have found thus far seem fairly trivial, or assume a single lambda. I am trying to create several API's and would like to reuse some logic / inject some AWS clients as needed. Thanks in adance!
So, it would appear the above is the correct pattern.
In my case, my issue was caused by lambda code version vs what the lambda was executing. Oops!
Cleaning up all the resources and redeploying them with the full implementation worked as expected.