In this article, I will walk you through the process of creating a DynamoDB table and connecting it to your Spring Boot application(No JPA). Let’s start.
What is DynamoDB?
Amazon DynamoDB as per DynamoDB site — Serverless, NoSQL, fully managed database with single-digit millisecond performance at any scale.
In this article we will create a DynamoDB table which we will use to store number of visitor to our website. We will provide an endpoint
/counter
using spring boot. Once user will call to this endpoint then counter value from DynamoDB will be incremented using spring boot service and returned as a response to user.
Step 1: Set Up Your DynamoDB Table
First things first, let’s create a DynamoDB table. Follow these steps:
- Log in to the AWS Management Console: Navigate to the DynamoDB service.
2. Create a new table: Click on “Create table” and provide a name for your table, here I am using visitor_counter
. Set the primary/partition key, here I am using counter_id
with data type String
.
3. Configure settings: You can leave the default settings for read/write capacity or customize them based on your application’s needs.
4. Create the table: Click on “Create” to finalize the table creation.
First it will show table with status Creating
, wait for some time.
After some time table Status
will be changed to Active. Now table is ready to use.
Step 2: Set Up Your Spring Boot Application
Now that we have our DynamoDB table, let’s set up our Spring Boot application to connect to it.
- Create an application:
Follow https://start.spring.io/ for custom application or use this link to download template with spring boot web dependency.
- You can use application which I created to perform these steps from github
2. Add dependencies: Add the following dependencies to your pom.xml
file:
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>dynamodb</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>dynamodb-enhanced</artifactId>
</dependency>
3. Add Model Class: create a model class with annotation @DynamoDbBean
annotation. Also, add @DynamoDbPartitionKey
to field which was used a partition key while creating DynamoDB table
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
@DynamoDbBean
public class Counter {
private String counter_id;
private Integer counter;
@DynamoDbPartitionKey
public String getCounter_id() {
return counter_id;
}
public void setCounter_id(String counter_id) {
this.counter_id = counter_id;
}
public Integer getCounter() {
return counter;
}
public void setCounter(Integer counter) {
this.counter = counter;
}
public void incrementCounter(){
this.counter++;
}
public Counter(String counter_id, Integer counter) {
this.counter_id = counter_id;
this.counter = counter;
}
public Counter() {
}
}
4. Add Service class : This class will perform DB operations.
package com.lab01.spring.backend;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import java.util.Optional;
@Component
public class DynamoDBService {
public final String tableName = "visitor_counter";
public final String recordId = "1001";
private DynamoDbClient getClient() {
Region region = Region.US_EAST_1;
return DynamoDbClient.builder()
.region(region)
.build();
}
private DynamoDbEnhancedClient enhancedClient() {
return DynamoDbEnhancedClient.builder()
.dynamoDbClient(getClient())
.build();
}
// Get counter value from database , save incremented and return incremented.
public Integer incrementAndReturnCounter() {
Counter counter = getCounterFromDynamoDB();
if (counter == null) {
throw new RuntimeException("Counter not available");
}
counter.incrementCounter();
saveCounter(counter);
return counter.getCounter();
}
private Counter getCounterFromDynamoDB() {
try {
DynamoDbTable<Counter> table = enhancedClient().table(tableName, TableSchema.fromBean(Counter.class));
Optional<Counter> counterOptional = table.scan().items().stream().filter(c -> c.getCounter_id().equals(recordId)).findFirst();
Counter counter;
if (counterOptional.isEmpty()) {
counter = new Counter(recordId, 0);
} else {
counter = counterOptional.get();
}
return counter;
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
}
return null;
}
private void saveCounter(Counter counter) {
try {
DynamoDbTable<Counter> table = enhancedClient().table(tableName, TableSchema.fromBean(Counter.class));
table.putItem(counter);
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
}
}
}
5. Add GET endpoint /counter
Add a Controller class with GET api /counter
— which will increment this value in DynamoDB and return that value as API response.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/counter")
public class CounterController {
private final DynamoDBService dynamoDBService;
public CounterController(DynamoDBService counterService) {
this.dynamoDBService = counterService;
}
@GetMapping
public int increment() {
return dynamoDBService.incrementAndReturnCounter();
}
}
Step 3: Test
With everything set up, now lets connect.
Start spring boot application either of these methods
- From IDE
- From Terminal using command
mvn spring-boot:run
Open Browser and hit http://localhost:8080/counter
You can verify these values inside DynamoDB console
Hit API again to see increment working.
Conclusion:
Congratulations! You’ve successfully created a DynamoDB table and connected it to your Spring Boot application. With DynamoDB’s scalability and Spring Boot’s ease of use, an application can handle any amount of data with lightning-fast performance.
Happy coding!