REST API using AWS Java SDK
Tags: aws, lambda, java, restapi
Published: 2020-09-22 18:29:48

In the [previous post](https://rajanpanchal.net/write-your-first-aws-lambda-in-java/), 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.

``` XML
<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.

```Java
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](https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/lambda+api.PNG)
Go to actions and create a new method of type `GET`. Select the following configuration:
![AWS Java SDK Rest API using Lambda Proxy Integration](https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/rest+method.PNG)
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](https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/deploy.PNG)
Use the URL generated to access the API
![AWS Java SDK Rest APIk](https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/url.PNG)

## Testing

Hit the URL in the browser and you should see the below response:
![AWS Java SDK Rest API using Lambda Proxy Integration](https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/access-api.PNG)

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](https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/log-group.PNG)

#### Source Code:

[![AWS Java SDK Rest API using Lambda Proxy Integration](https://github-readme-stats.vercel.app/api/pin/?username=rajanpanchal&repo=lambda-api-aws-sdk)](https://github.com/rajanpanchal/lambda-api-aws-sdk)
Here we complete our REST API with Lambda!

*If you like the post, feel free to share and follow me on [Twitter](https://twitter.com/PanchalRajan) for updates!*