
Spring Boot is the most popular Java application framework with +60% of Java developers reportedly using it. There is a broad ecosystem (libraries, tools and resources) and developer experience. Spring Boot on a server initializes the environment once and handles multiple requests with the same instance, whereas in AWS Lambda an execution environment is initialized on first invocation and can handle only one request at a time. Another environment is started if another request comes in while the execution environment is busy.
Spring Cloud AWS supports a subset of AWS services which drastically reduces the time needed to use their capabilities in a Spring Boot application. AWS services like Amazon RDS, Amazon SQS, Amazon SNS, Amazon S3, and more are already available. Spring Cloud AWS using Spring APIs and idioms to make it easy for Spring Boot developers to adapt above AWS services. For example, Spring Messaging API with SQS, Spring Cache API with Amazon ElasticSearch, emails via Amazon SES, bootstrap property sources with AWS Parameter Store or Secrets Manager.
Spring Cloud Function promotes the implementation of business logic via Function interface. You can use this in conjunction with AWS Lambda for payload translation, and to leverage Spring Boot features in functional environment.
Spring journey to AWS Lambda contains four steps:
AWS Lambda is invoked via Events (API Event, S3 Object Event, SQS Event, etc.). Events follow a certain structure, and this is different from accepting an HTTP connection. AWS Serverless Java Container is a library that acts as a conduit between Events and HTTP. It transforms events so that Spring can handle them as if it was an HTTP request.
Using AWS Serverless Java Container
If you still need to use @RestController in your SpringBoot application running on AWS Lambda,
then AWS Serverless Java Container
can be used which transforms events to framework specific
HTTP Request structure. This is mainly used when routing via @RestController, rely on POJO serialization,
and return HTTP status codes.
All you have to do is to add the library to your code and provide a configuration class.
AWS Serverless Java Container now supports Java 17 and SpringBoot 3. Refer this pet-store sample to learn more about its use.
spring-data-jpa vs spring-data-jdbcjackson vs jackon-jrlog4J2 vs SLF4J SimpleLoggerRestController vs FunctionHandler<Event>Prefer using Function interface, as mentioned above with Spring Cloud Function.
An AWS Lambda handler would look as the following:
@Component
public class UnicornPostFunction implements Function<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
@Override
public APIGatewayProxyResponseEvent apply(APIGatewayProxyRequestEvent input) {
try {
var unicorn = objectMapper.readValue(input.getBody(), Unicorn.class);
var savedUnicorn = unicornService.createUnicorn(unicorn);
return new APIGatewayProxyResponseEvent().withStatusCode(200).withBody(objectMapper.writeValueAsString(savedUnicorn));
} catch (Exception e) {
logger.error("Error creating unicorn", e);
return new APIGatewayProxyResponseEvent().withStatusCode(500).withBody("Error creating unicorn");
}
}
}
instead of @RestController:
@RestController
public class UnicornController {
//...
@PostMapping("/unicorns")
public ResponseEntity<Unicorn> createUnicorn(@RequestBody Unicorn unicorn) {
try {
var savedUnicorn = unicornService.createUnicorn(unicorn);
return ResponseEntity.ok(savedUnicorn);
} catch (Exception e) {
logger.error("Error creating unicorn", e);
throw new ResponseStatusException(INTERNAL_SERVER_ERROR, "Error creating unicorn", e);
}
}
}
GraalVM Native image
Use alternative compile time frameworks on the JVM (Micronaut, Quarkus)