AWS Lambda is built on top of Serverless technology which allows running your code without having to worry about any server maintenance and deployment. That is a very cool concept to build stateless applications. And REST API is essentially stateless which makes it a perfect candidate for Serverless. In this tutorial, I cover how to get started with AWS Lambda and API Gateway to build Rest APIs with Java. For that, we code a basic Hello World Lambda function. Then we use API Gateway to create /hello
endpoint.
This tutorial consists of three sections. An architectural overview which is then followed by how to create our Lambda function and the last section is about setting the infrastructure up to deploy our function. The last part involves the configuration of AWS API Gateway and the deployment of our Lambda function. It sounds a lot but no worries, we go through everything in details. Stay tuned!
Architectural overview
Our objective is to create a REST API endpoint that accepts POST
requests on /hello
path. And then returns responses in the JSON format. To achieve that first, we need to code a Lambda function which is explained in the next section. However, after writing the code we must set an API Gateway up that accept requests and redirects requests to the Lambda function as follows:
Writing Hello World Lambda function in Java
The first step of building a REST API to run in Serverless infrastructure is to code our function. Since we go with AWS Lambda we need to use the Lambda library provided by AWS.
We should start by creating a green field project. I use Maven here. To create the project we can use maven archetype
:
$ mvn archetype:generate -DgroupId=com.madadipouya.hello.world.lambda -DartifactId=java-lambda-example
After the project skeleton is ready, we need to add aws-lambda-java-core
as a maven dependency. To do so,
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
And since we must provide a fat jar file to AWS, we need to modify our build section in pom.xml
to include all dependency in the final .jar
file.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Now that we have everything ready, we must implement our Lambda function. We start by creating a class called MainFunction
in com.madadipouya.hello.world.lambda
package. Then we need to implement RequestHandler<I,O>
from aws-lambda
library to have access to Input
and Output
streams as follows:
package com.madadipouya.hello.world.lambda;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.madadipouya.hello.world.lambda.models.Request;
import com.madadipouya.hello.world.lambda.models.Response;
public class MainFunction implements RequestHandler<Request, Response> {
public Response handleRequest(Request request, Context context) {
Response response = new Response();
response.setMessage(String.format("Hello %s to AWS Lambda World!", request.getName()));
return response;
}
}
As you can see, the RequestHandler
accepts two generics as <code>Input<I>
and Output<O>
to access to the function input and output streams. The best way to deal with them is to create two POJOs,
package com.madadipouya.hello.world.lambda.models;
public final class Request {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
package com.madadipouya.hello.world.lambda.models;
public class Response {
private String message;
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
So the request JSON payload of the endpoint will be like this,
{
"name": "Geeky Hacker"
}
And this for the response,
{
"message": "Hello Geeky Hacker to AWS Lambda World!"
}
The last step is to build the project and create a fat jar file by running,
$ mvn clean package
You can access to the source code of the Hello World Lambda at the following link on GitHub:
https://github.com/kasramp/Java-AWS-Lambda-hello_world-example
Setting up AWS Lambda function and API Gateway
In this section, we focus on how to create a Lambda function in the AWS console and upload our hello world example. Then we create an API Gateway and hook it up with the Lambda function.
Creating a Lambda function in AWS
To create a Lambda function in AWS, first, we need to go to the AWS console, then select the data center that we want to create the Lambda function. After that search for Lambda in the search box.
Once we are the in the page, need to click on create function
button and select Author from scratch
option. Write down the function name and select Java 8 as runtime,
Then click create function
. Once redirected to another page, click on upload
and select the .jar
file of the example above. After that, we need to set the handler which consists of the package name and the class file name. For our example the handler name is com.madadipouya.hello.world.lambda.MainFunction::handleRequest
. After that click save.
Now we have done with the Lambda creation. The next step is to hook this up to the AWS API Gateway.
Setting up AWS API Gateway
To create an API Gateway, search it from the AWS console and click on it. Then click create API
button and configure it like the below picture:
Keep in mind the Gateway should be in the same data center with our Lambda function.
Once it’s created, we must configure it. To do that we need to add a new endpoint from the Action
menu, Create Resource
. We should provide a name and a path. Let’s name it Hello
and give /hello
path to it and click Create Resource
.
The next step is to create a method for our path, /hello
, from the Action
menu. We should select POST
and click create. After that, we must write the Lambda function name that we want this method to trigger,
Once, that’s done, confirm and click Save
. After that, we can test the Gateway to ensure it’s working. Once it’s confirmed, we can deploy it by clicking Action
menu and selecting Deploy API
. Which after selecting the stage or creating the function, it should provide a URL to use.
To test the API, we can use cURL like below:
$ curl -X POST -H "Content-Type: application/json" -d '{"name": "Geeky Hacker"}' URL/hello
And the result should be:
{
"message": "Hello Geeky Hacker to AWS Lambda World!"
}
And that’s all for this tutorial. As you can see it was not difficult at all to create an API with Lambda function and API Gateway 🙂