{{announcement.body}}
{{announcement.title}}

Your First Java AWS Lambda [Video]

DZone 's Guide to

Your First Java AWS Lambda [Video]

This video demonstrates how you can use AWS Lambda for a Java application with authentication through Cognito and API Gateway for an HTTP interface.

· Cloud Zone ·
Free Resource

Java

AWS Lambdas provide a convenient environment in which to run short-lived applications without having to worry about provisioning the underlying hardware or manage operating systems. In this post, we'll look at a simple Java application that can run as a Lambda.

The source code for this application is available on GitHub.

The video below is a screencast showing this sample application configured in AWS, complete with Cognito for authentication and API Gateway for an HTTP interface.


The first decision to make is whether this Lambda will be invoked by API Gateway through proxy integration, or non-proxy integration. We'll demonstrate the former in this post, as proxy integration appears to be the preferred solution, although the wording of that preference has softened over time.

You may also enjoy: Building Serverless on AWS Lambda

Here is the class containing the entry point method.

Java
 




x
16


 
1
package com.matthewcasperson;
2
 
          
3
import com.amazonaws.services.lambda.runtime.Context;
4
import com.google.gson.Gson;
5
 
          
6
import java.util.Map;
7
 
          
8
public class LambdaMethodHandler {
9
    public ProxyResponse handleRequest(
10
            final Map<String,Object> input,
11
            final Context context) {
12
        return new ProxyResponse(
13
                "200",
14
                new Gson().toJson(input));
15
    }
16
}


The method signature returns a ProxyResponse class, which has the structure required to support a proxy integration response (more on that class later). The first parameter accepts the JSON content supplied by API Gateway, so a map of strings to objects will support any JSON object structure. The second parameter contains details of the Lambda execution environment.

This method returns a status code of 200 (HTTP OK) and the supplied input object is embedded back into the response body. We do this to verify that the Lambda correctly received the input data.

The ProxyResponse class is required to expose three fields: body (the HTTP response body), headers (the HTTP headers) and  statusCode (the HTTP status code).

This class is nothing more than a data class, with the exception of the headers, which include the CORS Access-Control-Allow-Origin header predefined. This is done because while the API Gateway can implement most of the CORS exchange, some requests, such as any with an Authorization header, require the Lambda to return Access-Control-Allow-Origin header.

Java
 




xxxxxxxxxx
1
33


1
package com.matthewcasperson;
2
 
          
3
import java.util.HashMap;
4
import java.util.Map;
5
 
          
6
public class ProxyResponse {
7
    public final String statusCode;
8
    public final String body;
9
    public final Map<String, String> headers;
10
 
          
11
    public ProxyResponse(
12
            final String statusCode,
13
            final String body,
14
            final Map<String, String> headers) {
15
        this.headers = headers == null ? new HashMap<>() : headers;
16
        this.body = body;
17
        this.statusCode = statusCode;
18
        addCORSHeaders();
19
    }
20
 
          
21
    public ProxyResponse(
22
            final String statusCode,
23
            final String body) {
24
        this.headers = new HashMap<>();
25
        this.body = body;
26
        this.statusCode = statusCode;
27
        addCORSHeaders();
28
    }
29
 
          
30
    private void addCORSHeaders() {
31
        headers.put("Access-Control-Allow-Origin", "*");
32
    }
33
}



The sample application is packaged up as an UberJAR with the Maven Shade plugin, configured in the pom.xml file.

XML
 




xxxxxxxxxx
1
46


 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project>
3
    <modelVersion>4.0.0</modelVersion>
4
    <groupId>com.matthewcasperson</groupId>
5
    <artifactId>awslambdajava</artifactId>
6
    <version>1.0</version>
7
 
          
8
    <properties>
9
        <maven.compiler.target>1.8</maven.compiler.target>
10
        <maven.compiler.source>1.8</maven.compiler.source>
11
    </properties>
12
 
          
13
    <dependencies>
14
        <dependency>
15
            <groupId>com.amazonaws</groupId>
16
            <artifactId>aws-lambda-java-core</artifactId>
17
            <version>1.1.0</version>
18
        </dependency>
19
        <dependency>
20
            <groupId>com.google.code.gson</groupId>
21
            <artifactId>gson</artifactId>
22
            <version>2.8.6</version>
23
        </dependency>
24
    </dependencies>
25
 
          
26
    <build>
27
        <plugins>
28
            <plugin>
29
                <groupId>org.apache.maven.plugins</groupId>
30
                <artifactId>maven-shade-plugin</artifactId>
31
                <version>2.4.3</version>
32
                <configuration>
33
                    <createDependencyReducedPom>false</createDependencyReducedPom>
34
                </configuration>
35
                <executions>
36
                    <execution>
37
                        <phase>package</phase>
38
                        <goals>
39
                            <goal>shade</goal>
40
                        </goals>
41
                    </execution>
42
                </executions>
43
            </plugin>
44
        </plugins>
45
    </build>
46
</project>


Once packaged with the  mvn package command, we'll have a single self-contained JAR file that can be uploaded as a Lambda.

In the screenshot below I have created a Lambda, uploaded the JAR file and tested it through the Lambda console with the default test data. You can see the serialized  ProxyResponse class has been returned, embedding the supplied test data.

Further Reading

Java on AWS Using Lambda

AWS Lambda Best Practices

Topics:
aws ,lambda ,java ,aws lambda ,cognito ,json ,api gateway

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}