REST API using AWS Java SDK

REST API using AWS Java SDK

In the previous post, we looked at a simple Lambda handler using the AWS Java SDK. In this post, we're going to implement Rest API with Lambda (using Lambda Proxy Integration).

What is Lambda Proxy Integration

When a client submits an API request, API Gateway passes the request to the integrated Lambda function as-is, except that the order of the request parameters is not preserved. This request data includes the request headers, query string parameters, URL path variables, payload, and API configuration data.

The configuration data can include current deployment stage name, stage variables, user identity, or authorization context (if any). The backend Lambda function parses the incoming request data. The API gateway simply acts as a postman to pass requests and responses. One advantage is that you can change the implementation of the Lambda without impacting the API.

Let's implement using AWS Java SDK

Create an empty maven project and update the pom.xml with the following contents.

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.rajanpanchal</groupId>
    <artifactId>lambda-api-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>LambdaApiDemo</name>
    <description>Demonstrates API Request &amp; Response Using Lambda and Java SDK for AWS</description>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <aws.java.sdk.version>2.14.11</aws.java.sdk.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.java.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-events -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-events</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.2.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

We are adding 2 main dependencies here:

  1. aws-lambda-java-core - This provides RequestHandler
  2. aws-lambda-java-events - This provides APIGatewayProxyRequestEvent and APIGatewayProxyResponseEvent

Added 2 plugins:

  1. Compiler plugin - determines java version for the compiler.
  2. maven-shade-plugin - to generate fat jar aka Uber jar (with all dependencies)

Create a class LambdaHandler, with the following contents.

package net.rajanpanchal.handlers;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;

public class LambdaHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent requestEvent, Context context) {
        APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent();
        try {
            LambdaLogger logger = context.getLogger();
            logger.log("requestEventString:" + requestEvent.toString());
            logger.log("query string param:" + requestEvent.getQueryStringParameters());
            logger.log("headers:" + requestEvent.getHeaders());
            // fetching the value send in the request body
            String message = requestEvent.getBody();
            // Request request = gson.fromJson(message, Request.class);
            logger.log("message body:" + message);

            // setting up the response message
            responseEvent.setBody("Hello from Lambda!");
            responseEvent.setStatusCode(200);

            return responseEvent;

        } catch (Exception ex) {
            responseEvent.setBody("Invalid Response");
            responseEvent.setStatusCode(500);
            return responseEvent;
        }
    }
}

The above code is simple. requestEvent object is of type APIGatewayProxyRequestEvent. You will get headers, body, query-string, etc. from this object. responseEvent object is of type APIGatewayProxyResponseEvent. You can set response headers, body, status, etc in this object.

Now execute maven command mvn package to generate a jar file in the target folder. Login to AWS console, create Lambda function with Java 8 runtime, let it create execution role, and upload the jar file under Function Code section. In Basic Settings, set the handler name in format :

*net.rajanpanchal.handlers.LambdaHandler::handleRequest*

Now go to API Gateway, create a REST API AWS Java SDK Rest API using Lambda Proxy Integration Go to actions and create a new method of type GET. Select the following configuration: AWS Java SDK Rest API using Lambda Proxy Integration To enable proxy integration, make sure to check the checkbox. Save to create a method.

Go to actions and click deploy API and give the following information and click deploy. Lambda proxy integration using java sdk Use the URL generated to access the API AWS Java SDK Rest APIk

Testing

Hit the URL in the browser and you should see the below response: AWS Java SDK Rest API using Lambda Proxy Integration

Go to Cloud Watch, access Log Groups from the left-hand navigation, and access the logs corresponding to your lambda function. You should see the log statements from the lambda handler. AWS Java SDK Rest API using Lambda Proxy Integration

Source Code:

AWS Java SDK Rest API using Lambda Proxy Integration Here we complete our REST API with Lambda!

If you like the post, feel free to share and follow me on Twitter for updates!