Skip to content

Build Java REST API using API Gateway, AWS Lambda, DynamoDB & Serverless framework on AWS

In this tutorial let’s take a look at the process involved in building a REST API in Java using API Gateway, AWS Lambda, DynamoDB & Serverless framework on AWS.

Prerequisites

  1. AWS account setup with AWS Access Key Id and Secret Access Key
  2. AWS CLI installed in your local machine
  3. Java installed in your local machine
  4. Install Node.js & npm on your local machine

Initial Setup

  1. Install serverless framework on your local machine by running the below npm command
$ npm install -g serverless

2. Verify serverless installation

$ serverless -v
Framework Core: 1.71.3
Plugin: 3.6.12
SDK: 2.3.0
Components: 2.30.11

Create Serverless project

Run the below serverless command to generate serverless project using the aws-java-maven template

$ serverless create --template aws-java-maven --name serverless-restapi
Serverless: Generating boilerplate...
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.71.3

 -------'Serverless: Successfully generated boilerplate for template: "aws-java-maven"

Optionally you can also specify a path using the --path, to create the project in a path different than the current folder.
You should see a project created like below, (I use IntelliJ IDEA)

serverless.yml is the file where you define your whole service which includes lambda functions, permissions, environment variables, infrastructure resources and so on. The generated serverless.yml file will have the definitions commented out, modify the serverless.yml file to define your service

Define Employee API & required resources in your serverless.yml file

Now let’s scan through the various sections in the above serverless.yml file,

  1. service — name of your service
  2. provider — defines the cloud provider you want to use, runtime and different stuffs.
    Here we are using aws as the cloud provider, you can also use different cloud providers with serverless framework like azure for Microsoft Azure, google for Google Cloud Platform etc.
    And since we’re building a Java REST API, the runtime is java8 (you may choose any latest java runtimes as well)
    iamRoleStatements — defines the permissions required for the lambda function, and in this case permissions required for the lambda function to access the DynamoDB employeeTable as defined in the Resource subsection
  3. environment — environment variables here, for this example we don’t need any, but have just added here for an example
  4. package — defines how we want to package our code
  5. functions — defines the lambda functions and handler mappings
    events — events that triggers the respective functions, here we’re using a http trigger which creates an API Gateway http endpoint that triggers the respective functions like in this case createEmployee & getEmployees function
  6. resources — defines the resources your functions use, and in this case we’re defining an employeeTable in DynamoDB, this name should match the Resource defined in the iamRoleStatements section, so that the function can access the dynamoDB table
    TableName defines the actual DynamoDB table that will be created

pom.xml

Serverless framework generates your maven project with hello as the artifactId like below,

<groupId>com.serverless</groupId>
<artifactId>hello</artifactId>
<packaging>jar</packaging>
<version>dev</version>
<name>hello</name>

So our modified pom.xml will look like the one below,

<groupId>com.serverless</groupId>
<artifactId>employee-serverless-restapi</artifactId>
<packaging>jar</packaging>
<version>dev</version>
<name>employee-serverless-restapi</name>

Since we want our lambda function to access the DynamoDB table, we’ll need to add the aws-java-sdk-dynamodb maven dependency to our pom file,

<dependency>
  <groupId>com.amazonaws</groupId>
  <artifactId>aws-java-sdk-dynamodb</artifactId>
  <version>1.11.804</version>
</dependency>

Defining Employee entity using DynamoDB annotations

  1. @DynamoDBTable — defines the actual dynamoDB table to associated with this entity
  2. @DynamoDBAutoGeneratedKey — can be used with a range or hash key to generate a random UUID (only String datatype keys can be auto-generated)
  3. @DynamoDBHashKey — denotes the partition key for the table
  4. @DynamoDBRangeKey — denotes the sort key for the table
  5. @DynamoDBAttribute — to define additional table attributes

Saving Employee to the DynamoDB table

  1. AmazonDynamoDBClientBuilder — client to access the DynamoDB
  2. DynamoDBMapper — to map your DynamoDB tables to the Java object, this enables the code to perform various CRUD operations on your table. In this case we use the dynamoDBMapper.save() method to save the employee entity to the DB

Get list of all employees from the DynamoDB table

DynamoDBScanExpression is used to filter results based on attributes, since we want to get all the employees from the DB, no filtering has been applied, but if you want to filter based on id or name or any other attributes you can use the withFilterExpression & withExpressionAttributeValues methods
Then use dynamoDBMapper.scan() method to get the list of all employees by passing in the Employee.class & dynamoDBScanExpression as parameters

Building the Handlers

As shown in the initial project structure screenshot, the Serverless framework has already generated a Handler class, use that as a template to call the respective create & retrieveAll methods to save and list employees respectively. Below is a sample handleRequest implementation, (refer the GitHub repo for the full source code)

List<Employee> employeeList = new Employee().retrieveAll();

return ApiGatewayResponse.builder()
        .setStatusCode(200)
        .setObjectBody(employeeList)
        .build();

Connecting your AWS account to your local machine

$ export AWS_ACCESS_KEY_ID = <<your AWS access key id goes here>>
$ export AWS_SECRET_ACCESS_KEY = <<your AWS secret key goes here>>
$ export AWS_DEFAULT_REGION = us-east-1 <<or your preferred region>>$ aws sts get-caller-identity //to verify the account setup
{
    "UserId": "SAMPLEUSERID",
    "Account": "12345",
    "Arn": "arn:aws:iam::12345:user/Admin"
}

Deploying your Serverless app to AWS

$ sls deploy

Yes, you read it correct, it’s easy peasy now to deploy your serverless app to AWS, with just one command,

you can use sls or serverless based on your convenience. Once you run this command, the Serverless framework will start deploying your app to AWS like below and displays the service information, once the deployment is completed,

As you can see above in the endpoints section the API gateway endpoints are shown. You can also login to you AWS Console and verify the various services that got deployed like API Gateway, AWS Lambda function, DynamoDB table etc.

Testing your Serverless Employee REST API

Use the endpoints shown in the output above to create and list all employees.
Let’s use a simple curl command to test the endpoints, you can also you use Postman or other API testing tools that you’d prefer for testing

Creating an Employee record in the DB..

$ curl -X POST https://qe4xy07ew7.execute-api.us-east-1.amazonaws.com/dev/employee -d '{"name":"Sash","department":"HRD"}'//output returned by API below
{"id":"ba29b4fb-ab7a-4425-b590-76c5bf491801" ,"name":"Jack", "department":"HRD"}

As you see above, we just posted a request to the API with name and department alone, the @DynamoDBAutoGeneratedKey associated with the id generated a random UUID and saved it to the DB.

Retrieving all employees from the DB..

$ curl https://qe4xy07ew7.execute-api.us-east-1.amazonaws.com/dev/employee//output returned by API below
[{"id":"ba29b4fb-ab7a-4425-b590-76c5bf491801","name":"Sash","department":"HRD"},
{"id":"220f8a4f-ddbd-4332-a88c-a23aaacbf0ee","name":"Hash","department":"PT"}]

What if there’s an issue

We would need logs to debug and fix an issue, with serverless framework that’s easy peasy too, use the below command to get logs associated with your respective function. Here we can get the logs for createEmployee function like this — serverless logs --function createEmployee

SourceCode

TaDa! — That’s how you build an easy peasy AWS serverless Java REST API using the Serverless framework.

This post is originally published at https://medium.com/@saravaneshh/build-java-rest-api-using-api-gateway-aws-lambda-dynamodb-serverless-framework-on-aws-95d1f2394087

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.