Getting started with AWS Lambda and API gateway to building Rest APIs

AWS Lambda Java

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:

AWS-Lambda-Architectural-Overview

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,

Create-Lambda-function

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.

Configuring-Lambda-function

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:

API-Gateway-creation-page

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.

API-Gateway-resource-creation

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,

API-Gateway-select-Lambda-function

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 🙂

Inline/featured images credits