Spring Boot + DynamoDB Crud Example
Overview
In this tutorial we will be looking at creating Spring Boot + AWS DynamoDB Crud Example.
AWS DynamoDB Tutorial :
- AWS DynamoDB Setup
- Spring Boot + DynamoDB Crud Example
- AWS DynamoDB Interview Questions and Answers
What is DynamoDB?
DynamoDB is NoSQL database, it can handle structured or semi structured data, including JSON
documents. DynamoDB scales to accommodate very large amounts of data and very large number of users
seamlessly.
SQL is the standard for storing and retrieving data. Relational databases have a wide range of
tools available for simplifying the development of database-driven applications, however all of
these tools uses SQL.
Prerequisites
Follow AWS DynamoDB Setup to get the below Prerequisites.
- AWS Account
- Get the Access Key ID and Secret Access Key from AWS Account
- Creation of DynamoDB Table on AWS Console
Now, let's create the Spring Boot Project from Spring Initializer site https://start.spring.io/.
Project Structure
Maven Dependency
Add aws-java-sdk-dynamodb for DynamoDB.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.techgeeknext</groupId>
<artifactId>SpringBoot-Dynamodb-Example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot-Dynamodb-Example</name>
<description>Demo project for Spring Boot + Dynamodb Example</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
<version>1.11.857</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application Properties
Provide below properties to connect with AWS DynamoDB.
server.port = 8081
## replace below url with your aws region (aws-region)
## https://dynamodb.aws-region.amazonaws.com
aws.dynamodb.endpoint=https://dynamodb.ap-south-1.amazonaws.com
## your aws region
aws.region=ap-south-1
## aws generate aws access key after creating user
aws.dynamodb.accessKey= *********
## aws generate aws secret key after creating user
aws.dynamodb.secretKey= ************
DynamoDB Configuration
package com.techgeeknext.config;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DynamoDBConfiguration {
@Value("${aws.dynamodb.endpoint}")
private String dynamodbEndpoint;
@Value("${aws.region}")
private String awsRegion;
@Value("${aws.dynamodb.accessKey}")
private String dynamodbAccessKey;
@Value("${aws.dynamodb.secretKey}")
private String dynamodbSecretKey;
@Bean
public DynamoDBMapper dynamoDBMapper() {
return new DynamoDBMapper(buildAmazonDynamoDB());
}
private AmazonDynamoDB buildAmazonDynamoDB() {
return AmazonDynamoDBClientBuilder
.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(dynamodbEndpoint,awsRegion))
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials(dynamodbAccessKey,dynamodbSecretKey)))
.build();
}
}
Data Model
Create Customer model to represent the data stored in DynamoDB.
package com.techgeeknext.entity;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAutoGeneratedKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@DynamoDBTable(tableName = "customer")
public class Customer {
@DynamoDBHashKey
@DynamoDBAutoGeneratedKey
private String customerId;
@DynamoDBAttribute
private String firstName;
@DynamoDBAttribute
private String lastName;
@DynamoDBAttribute
private String email;
@DynamoDBAttribute
private Address address;
}
Create Address Data Model to map with above class as address object.
package com.techgeeknext.entity;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDocument;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@DynamoDBDocument
public class Address {
@DynamoDBAttribute
private String line1;
@DynamoDBAttribute
private String city;
@DynamoDBAttribute
private String country;
}
Repository
The entry point for DynamoDB is the DynamoDBMapper class. It provides access to a DynamoDB endpoint and allows you to access your data from different tables, perform various CRUD operations, and execute queries and scans table.
package com.techgeeknext.repository;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue;
import com.techgeeknext.entity.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class CustomerRepository {
@Autowired
private DynamoDBMapper dynamoDBMapper;
public Customer saveCustomer(Customer customer) {
dynamoDBMapper.save(customer);
return customer;
}
public Customer getCustomerById(String customerId) {
return dynamoDBMapper.load(Customer.class, customerId);
}
public String deleteCustomerById(String customerId) {
dynamoDBMapper.delete(dynamoDBMapper.load(Customer.class, customerId));
return "Customer Id : "+ customerId +" Deleted!";
}
public String updateCustomer(String customerId, Customer customer) {
dynamoDBMapper.save(customer,
new DynamoDBSaveExpression()
.withExpectedEntry("customerId",
new ExpectedAttributeValue(
new AttributeValue().withS(customerId)
)));
return customerId;
}
}
Take a look at our suggested posts:
Crud Rest Controller
Create a Rest Controller class to provide crud enpoints and autowire with repository to perform respective operation on DynamoDB.
package com.techgeeknext.controller;
import com.techgeeknext.entity.Customer;
import com.techgeeknext.repository.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class CustomerController {
@Autowired
private CustomerRepository customerRepository;
@PostMapping("/add/customer")
public Customer saveCustomer(@RequestBody Customer customer) {
return customerRepository.saveCustomer(customer);
}
@GetMapping("/get/customer/{id}")
public Customer getCustomerById(@PathVariable("id") String customerId) {
return customerRepository.getCustomerById(customerId);
}
@DeleteMapping("/delete/customer/{id}")
public String deleteCustomerById(@PathVariable("id") String customerId) {
return customerRepository.deleteCustomerById(customerId);
}
@PutMapping("/update/customer/{id}")
public String updateCustomer(@PathVariable("id") String customerId, @RequestBody Customer customer) {
return customerRepository.updateCustomer(customerId,customer);
}
}
Test
Run the Spring Boot Application and follow the below steps to test the application response.
- Create the Customer data, use HTTP POST http://localhost:8081/add/customer
- GET customer by Id using HTTP GET (http://localhost:8081/delete/customer/{id}) http://localhost:8081/delete/customer/317853db-5257-4129-87b2-b208b6720b40
- To delete the customer, use HTTP DELETE (http://localhost:8081/delete/customer/{id}) http://localhost:8081/delete/customer/317853db-5257-4129-87b2-b208b6720b40
- To update the customer, use HTTP PUT (http://localhost:8081/update/customer/{id}) http://localhost:8081/update/customer/317853db-5257-4129-87b2-b208b6720b40 and provide Customer details to update
Also, you can see the output in AWS DynamoDB Console.
Download Source Code
The full source code for this article can be found on below.Download it here - Spring Boot + DynamoDB Crud Example