Comprehensive Guide to Using the DynamoDB Enhanced Client Over DynamoDBMapper
First of all, we should know why we are using DynamoDb Clients. Prior to that, what is client actually.? Client: Here the client is referred to a SDK code which connects to the Cloud SaaS product that we use. So it is clear that we are going to connect our code with AWS DynamoDB.
?What is the problem with DynamoDBMapper? While there are no major issues, it’s important to understand why we should use the DynamoDB Enhanced Client instead of DynamoDB Mapper.
To make it more clear in tabulation,
Now Let is implement the enhanced client using Java.
First create a maven Java project. And add the enhanced client dependency in the pom.xml in the file directory
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>dynamodb-enhanced</artifactId>
<version>2.25.60</version>
</dependency>
</dependencies>
You can also refer in maven repository: https://mvnrepository.com/artifact/software.amazon.awssdk/dynamodb-enhanced
After this, now you can enjoy the dynamoDb-enhanced client in your code base. But still we need create objects and configurations for connecting the AWS DynamoDb.
Before starting the code. Let’s see what we need to do in AWS to create a table in DynamoDb. Ofcource, we need to create table before writing the code to connect. Go to AWS console. If you don’t have one. Please get one.? Go to this console [https://us-east-1.console.aws.amazon.com/dynamodbv2/home?region=us-east-1#service] to create a table.
Watch the above video to get a brief introduction and how to create a table. In the above video resource they have created a table named “Customer” and specified the partition key as “customer_id”. we will follow the same to create the table let’s look over the code.
Note: You can write your own. Just to follow some pattern, I might suggest some package structure that I usually follow.
Create a package inside org.example package, naming “configuration”. As we discussed don’t forget to add the dependency in pom.xml first.
Inside configuration package create “Configuration.java” and create a singleton class to avoid creation of multiple client instances.
public class Configuration {
private static final AtomicReference<DynamoDbClient> dynamoDbClient = new AtomicReference<>();
private static final AtomicReference<DynamoDbEnhancedClient> dynamoDbEnhancedClient = new AtomicReference<>();
private Configuration() {
}
private static DynamoDbEnhancedClient getDynamoDbEnhancedClient() {
if (dynamoDbEnhancedClient.get() == null) {
dynamoDbEnhancedClient.compareAndSet(null, DynamoDbEnhancedClient.builder().dynamoDbClient(getDynamoDbClient()).build());
}
return dynamoDbEnhancedClient.get();
}
private static DynamoDbClient getDynamoDbClient() {
if (dynamoDbClient.get() == null) {
dynamoDbClient.compareAndSet(null, DynamoDbClient.builder()
.credentialsProvider(new AwsCredentialsProvider() {
@Override
public AwsCredentials resolveCredentials() {
return new AwsCredentials() {
@Override
public String accessKeyId() {
return "YOUR_ACCESS_KEY_ID";
}
@Override
public String secretAccessKey() {
return "YOUR_SECRET_KEY_ID";
}
};
}
})
.region(Region.of("us-east-1"))
.build());
}
return dynamoDbClient.get();
}
public static DynamoDbEnhancedClient initializeDynamoDbEnhancedClient() {
return getDynamoDbEnhancedClient();
}
}
Make sure the region is the same as the one where the table was created. In this example, I created the table in the us-east-1 region. then just call “initializeDynamoDbEnhancedClient” to get the instance of “DynamoDbEnhancedClient”.
To get the “accessKeyId” and “secretKeyId” from the AWS IAM console by creating a user. [https://us-east-1.console.aws.amazon.com/iam/home?region=us-east-1#/users/create]. You can create the it in any name.?
After creating you will redirected to set Permisions page.
Select “AmazonDynamoDbFullAccess” and click next. Then click on the created user and go to “Security credential” and click “Create access key”
After clicking “Create access key”?—?select local code and click next -> Create access key.
Hurrah! you have got the accessKeyId and secretKeyId.
Note: Keep your accessKeyId and secretKeyId safely. Exposing it will cost you bills when others start using it. So be cautious. And I don’t recommend you using accessKeyId and secretKeyId directly. Instead create a defaultClient by referring the documentation. [https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html]
Now, create a package named model inside org.example. And create a “Customer.java” and create necessary attributes, that we will reflect the same in dynamoDb.
@DynamoDbBean
public class Customer {
private String customerId;
private String name;
private String dob;
private String email;
private String mobileNumber;
public Customer() {
}
@DynamoDbPartitionKey
@DynamoDbAttribute(value = "customer_id")
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public Customer(String customerId, String name, String dob, String email, String mobileNumber) {
this.customerId = customerId;
this.name = name;
this.dob = dob;
this.email = email;
this.mobileNumber = mobileNumber;
}
}
The @DynamoDbBean annotation is required to create a bean, which will act as an ORM between our code and DynamoDB. Also don’t forget to annotate The @DynamoDbPartitionKey annotation is used on the getter method to specify the partition key of the DynamoDB table.?
Still only creating bean is not enough, After creating the pojo class, create a TableSchema for above created bean.?
public static final TableSchema<Customer> CUSTOMER_TABLE_SCHEMA = TableSchema
.fromBean(Customer.class);
With the TableSchema that we created with name “CUSTOMER_TABLE_SCHEMA”. Now we should create DynamoDbTable.
public class Main {
public static final TableSchema<Customer> CUSTOMER_TABLE_SCHEMA = TableSchema
.fromBean(Customer.class);
public static void main(String[] args) {
DynamoDbEnhancedClient dynamoDbEnhancedClient = Configuration.initializeDynamoDbEnhancedClient();
// 1st param -> table name - Customer
// 2nd param -> TableSchema of the table
DynamoDbTable<Customer> dynamoDbTable = dynamoDbEnhancedClient.table("Customer", CUSTOMER_TABLE_SCHEMA);
// Creating dummy object
Customer customer = new Customer();
customer.setCustomerId("12");
customer.setDob("10.10.2001");
customer.setEmail("[email protected]");
customer.setMobileNumber("986542120");
// Inserting data to DynamoDb Customer table.
dynamoDbTable.putItem(customer);
// Get data from DynamoDb Customer table.
Key getKey = Key.builder().partitionValue("12").build();
dynamoDbTable.getItem(getKey);
// Delete an item in DynamoDb Customer table.
Key deleteKey = Key.builder().partitionValue("12").build();
dynamoDbTable.deleteItem(deleteKey);
// Update an item in DynamoDb Customer table.
customer.setMobileNumber("12392834231");
dynamoDbTable.putItem(customer);
}
}
Result (only implemented putItem):
Here, we have the complete implementation of CRUD operations in DynamoDB. Using this, you can connect to and work with DynamoDB seamlessly.?
This is the Github link, where you can refer to the source code: https://github.com/Hari-Nikesh-R/amazon-enhanced-client-reference?:)
Also find me article in medium as well - https://medium.com/@hari.nikesh.r.cce/comprehensive-guide-to-using-the-dynamodb-enhanced-client-over-dynamodbmapper-fa343b51b3a5
Happy learning :)