Search code examples
javaspring-bootaws-lambdarequesthandler

Spring boot code integration with AWS RequestStreamHandler


I have a spring boot application with 2 GET end point. I am trying to include Lambda handler request and deploy as AWS Lambda function.

As a first step, I added below code for RequestStreamHandler.

public class AWSLambdaHandler implements RequestStreamHandler {
    private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
    static {
        try {
            handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(AWSTestApplication.class);
        } catch (ContainerInitializationException e) {
            // Re-throw the exception to force another cold start
            e.printStackTrace();
            throw new RuntimeException("Could not initialize Spring Boot application", e);
        }
    }
    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        handler.proxyStream(inputStream, outputStream, context);
        // just in case it wasn't closed by the mapper
        outputStream.close();
    }
}

Application class:

package com.example.awstest.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AWSTestApplication  extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(AWSTestApplication.class, args);
    }
}

Q: I have 2 GET end points in this spring boot service. Is this way of implementing Lambda handler request is enough or Do I need to add more code for the lambda function to handle this end point requests differently?

Controller class (just for the question 2):

@RestController

public class AWSTestController {

        @Autowired
        private AWSTestServiceDAO awstestServiceDAO;

        @CrossOrigin(origins = "*")
        @GetMapping("/searchAllData")
        public List<TESTData> searchAllData() {

            List<TESTData> dataList = awstestServiceDAO.getAllData();
            return dataList;
         }

        @CrossOrigin(origins = "*")
        @GetMapping("/searchDataByUser/{userno}")
        public List<TESTData> searchDataByUser(@PathVariable Integer userno) {

            List<TESTData> dataList = awstestServiceDAO.findDataByMemberNo(userno);
            return dataList;
        }

}

Solution

  • The error you are experiencing is related to the method getAwsProxyHandler() in the SpringBootLambdaContainerHandler class. The error message indicates that the method is expecting a parameter of type Class<? extends WebApplicationInitializer>, but you are passing AWSTestApplication.class, which is of type Class.

    To fix this error, you can try the following:

    Ensure that AWSTestApplication implements the WebApplicationInitializer interface. If it doesn't already, you can modify your application class as follows:

    @SpringBootApplication
    public class AWSTestApplication extends SpringBootServletInitializer 
    implements WebApplicationInitializer {
        // ... your code ...
    }
    

    Update the getAwsProxyHandler() call in your AWSLambdaHandler class to use a wildcard (?) for the generic type:

    handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(AWSTestApplication.class);
    

    By using Class<?> instead of Class, it should resolve the type mismatch error.

    Regarding your second question about handling different endpoint requests in the Lambda function, you can achieve that by implementing separate methods in your AWSTestController class for each endpoint. The code you provided already includes two GET endpoints: /searchAllData and /searchDataByUser/{userno}. These endpoints can be invoked by making GET requests to the corresponding URLs.

    Make sure you configure the necessary dependencies and mappings in your Spring Boot application to handle these requests correctly.