Spring Boot Lambda API Implementation

Spring Boot Lambda API Implementation

Creating a Spring Boot Lambda on AWS

Learn how to build and deploy a simple spring boot based AWS lambda and then automate its deployment with Terraform.

full course
  1. Spring Boot Lambda Prerequisites
  2. Spring Boot Lambda Implementation
  3. Spring Boot Lambda API Implementation
  4. Terraform Setup and First Install
  5. Terraform Centralized State Management
  6. Automated Terraform Deploy Using Github Actions
  7. Confirming the Continuous Deployment Pipeline

We’ve got a ‘working’ lambda now, but we can’t actually use it anywhere. The easiest thing to do at this point is add an API Gateway trigger to our function as a new lambda. This will require a little bit of work to make an API Gateway adapter to our service and then add the API Gateway trigger.

Start a New Branch

$ git checkout -b apifunction
Switched to a new branch 'apifunction'

Create an API Gateway Function

in our function directory make a new class HelloWorldAPIFunction

package com.bullyrooks.helloworldlambda.function;


import com.bullyrooks.helloworldlambda.function.dto.HelloWorldRequest;
import com.bullyrooks.helloworldlambda.function.dto.HelloWorldResponse;
import com.bullyrooks.helloworldlambda.service.HelloWorldService;
import com.bullyrooks.helloworldlambda.service.vo.HelloWorld;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import java.util.function.Function;

@Component
@Slf4j
public class HelloWorldAPIFunction implements
        Function<Message<HelloWorldRequest>, Message<HelloWorldResponse>> {
    @Autowired
    HelloWorldService helloWorldService;

    @Override
    public Message<HelloWorldResponse> apply(Message<HelloWorldRequest> input) {
        log.info("input message: {}", input);
        HelloWorld response = helloWorldService.helloWorld(input.getPayload().getName());
        HelloWorldResponse messageResponse = HelloWorldResponse.builder()
                .response(response.getResponse())
                .build();
        log.info("got response: {}", response);
        Message returnMessage = MessageBuilder.withPayload(response)
                .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .setHeader("statuscode", HttpStatus.OK.value())
                .build();
        log.info("Returning Message: {}", returnMessage);
        return returnMessage;
    }
}

The API Gateway adapter operates on Message objects which will contain JSON serializable messages. We’re going to use HelloWorldRequest and HelloWorldResponse as DTO to serialize the request and response. The rest of this function just transforms the DTO and makes the service call and transforms the response back. There is a little bit of trickiness in that the Message headers will contain the HTTP information that we’ll use in the API Gateway (i.e. statuscode). However, this is exactly inline with our ports and adapters design mindset.

Finally, we need to explicitly define the bean so that the SpringBootApiGatewayRequestHandler can find it. Add these lines to the HelloworldLambdaApplication class

    @Bean
    HelloWorldAPIFunction apiFunction() {
        return new HelloWorldAPIFunction();
    }

That should be it. Lets build the jar

$ mvn clean package
...
[INFO] Attaching shaded artifact.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  8.638 s
[INFO] Finished at: 
[INFO] ------------------------------------------------------------------------

Create the Lambda

We’re going to create the lambda the exact same way with a few minor changes.

The handler will be org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler::handleRequest and the environment variable FUNCTION_NAME will change to apiFunction

Add the API Gateway Trigger

On the function overview page, click Add trigger

From the drop down choose API Gateway

Choose Create an API, HTTP API and Open security. Then hit Add

You should see a green box that says the trigger was added

Testing the Lambda

You won’t be able to use the Test tab here. The lambda is now expecting a Message object, which you probably don’t want to have to create (although there are templates for it). Instead we’re going to test via Postman (or whatever HTTP tool you prefer).

Go to the API Gateway trigger and navigate to the details page to find the URL that the API Gateway is exposing the lambda as.

Click on API Gateway

Open up the Details section and copy out the URL for the API endpoint

Paste it into postman and make a body for our request:

{
    "name":"bullyrook"
}

You should see a successful response.

That’s it for now. However, creating all of these objects in AWS manually is tedious and prone to risk. In the next sections I’ll show you how to automate the deployment via Terraform.

Commit and Merge

$ git status
$ git add .
$ git commit -m "api triggered lambda"
$ git push --set-upstream origin apifunction
$ git checkout main
$ git merge apifunction
$ git push

0 comments on “Spring Boot Lambda API ImplementationAdd yours →

Leave a Reply

Your email address will not be published. Required fields are marked *