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 & 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:
- aws-lambda-java-core - This provides
RequestHandler
- aws-lambda-java-events - This provides
APIGatewayProxyRequestEvent
andAPIGatewayProxyResponseEvent
Added 2 plugins:
- Compiler plugin - determines java version for the compiler.
- 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
Go to actions and create a new method of type GET
. Select the following configuration:
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.
Use the URL generated to access the API
Testing
Hit the URL in the browser and you should see the below response:
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.
Source Code:
Here we complete our REST API with Lambda!
If you like the post, feel free to share and follow me on Twitter for updates!
Top comments (2)
Cool. I don't even need a little time with this to know it is insanely cool. I'd welcome a second conversation about API Gateway v2 and java. v2 is named HTTP and v1 is named REST, right.
Thanks! V2 supports HTTP APIs