DynamoDB in a Spring Boot Application Using Spring Data

Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. Spring Data for DynamoDB simplifies the integration of Spring Boot applications with DynamoDB. This tutorial will guide you through the process of setting up and using DynamoDB in a Spring Boot application using Spring Data.

Prerequisites

  • JDK 17 or later
  • Maven or Gradle
  • AWS Account (for DynamoDB access)
  • IDE (IntelliJ IDEA, Eclipse, etc.)

Step 1: Set Up a Spring Boot Project

1.1 Create a New Spring Boot Project

Use Spring Initializr to create a new project with the following dependencies:

  • Spring Web
  • Spring Data DynamoDB

Download and unzip the project, then open it in your IDE.

1.2 Add DynamoDB Dependencies

Add the required DynamoDB dependencies to your pom.xml (for Maven) or build.gradle (for Gradle) if not added via Spring Initializr.

For Maven:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-dynamodb</artifactId>
    <version>1.12.200</version>
</dependency>
<dependency>
    <groupId>com.github.derjust</groupId>
    <artifactId>spring-data-dynamodb</artifactId>
    <version>5.2.5</version>
</dependency>

For Gradle:

implementation 'com.amazonaws:aws-java-sdk-dynamodb:1.12.200'
implementation 'com.github.derjust:spring-data-dynamodb:5.2.5'

Step 2: Configure DynamoDB in Spring Boot

2.1 Create AWS Configuration

Create a configuration class for DynamoDB to set up the AWS credentials and DynamoDB client.

package com.example.demo.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 org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableDynamoDBRepositories(basePackages = "com.example.demo.repository")
public class DynamoDBConfig {

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        return AmazonDynamoDBClientBuilder.standard()
                .withEndpointConfiguration(
                        new AwsClientBuilder.EndpointConfiguration("dynamodb.us-west-2.amazonaws.com", "us-west-2"))
                .withCredentials(new AWSStaticCredentialsProvider(
                        new BasicAWSCredentials("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY")))
                .build();
    }
}

Explanation:

  • @Configuration: Marks this class as a source of bean definitions.
  • @EnableDynamoDBRepositories: Enables DynamoDB repositories and specifies the base package for repository scanning.
  • amazonDynamoDB(): Configures the DynamoDB client with endpoint and credentials.

2.2 Configure application.properties

Set up the application properties for your project. This file is located in the src/main/resources directory.

# src/main/resources/application.properties

spring.application.name=dynamodb-demo

Step 3: Define the Entity Class

3.1 Create the Product Entity

Create an entity class to represent a product in the DynamoDB table.

package com.example.demo.entity;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName = "Product")
public class Product {

    private String id;
    private String name;
    private String description;
    private double price;

    @DynamoDBHashKey(attributeName = "id")
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @DynamoDBAttribute(attributeName = "name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @DynamoDBAttribute(attributeName = "description")
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @DynamoDBAttribute(attributeName = "price")
    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

Explanation:

  • @DynamoDBTable(tableName = "Product"): Specifies the table name in DynamoDB.
  • @DynamoDBHashKey: Indicates the primary key attribute.
  • @DynamoDBAttribute: Maps the field to the corresponding attribute in the DynamoDB table.

Step 4: Create the Repository Interface

4.1 Create the ProductRepository

Create a repository interface to perform CRUD operations on the Product entity.

package com.example.demo.repository;

import com.example.demo.entity.Product;
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.springframework.data.repository.CrudRepository;

@EnableScan
public interface ProductRepository extends CrudRepository<Product, String> {
}

Explanation:

  • @EnableScan: Enables scanning of the DynamoDB table for queries.
  • CrudRepository<Product, String>: Provides CRUD operations for the Product entity.

Step 5: Create Service and Controller Layers

5.1 Create the ProductService

Create a service class to handle business logic related to products.

package com.example.demo.service;

import com.example.demo.entity.Product;
import com.example.demo.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    public Iterable<Product> getAllProducts() {
        return productRepository.findAll();
    }

    public Optional<Product> getProductById(String id) {
        return productRepository.findById(id);
    }

    public Product createProduct(Product product) {
        return productRepository.save(product);
    }

    public void deleteProduct(String id) {
        productRepository.deleteById(id);
    }
}

Explanation:

  • @Service: Marks the class as a service component in Spring.
  • ProductRepository: Injected to interact with the database.

5.2 Create the ProductController

Create a REST controller to expose endpoints for interacting with products.

package com.example.demo.controller;

import com.example.demo.entity.Product;
import com.example.demo.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;

@RestController
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping
    public Iterable<Product> getAllProducts() {
        return productService.getAllProducts();
    }

    @GetMapping("/{id}")
    public Optional<Product> getProductById(@PathVariable String id) {
        return productService.getProductById(id);
    }

    @PostMapping
    public Product createProduct(@RequestBody Product product) {
        return productService.createProduct(product);
    }

    @DeleteMapping("/{id}")
    public void deleteProduct(@PathVariable String id) {
        productService.deleteProduct(id);
    }
}

Explanation:

  • @RestController: Marks the class as a REST controller.
  • @RequestMapping("/products"): Maps the controller to /products endpoint.
  • @GetMapping, @PostMapping, @DeleteMapping: Maps HTTP GET, POST, and DELETE requests respectively.
  • @RequestBody: Binds the HTTP request body to the Product parameter.
  • @PathVariable: Binds the URI template variable to the method parameter.

Step 6: Running and Testing the Application

6.1 Run the Application

Run the Spring Boot application using your IDE or the command line:

./mvnw spring-boot:run

6.2 Test the Endpoints

Use a tool like Postman or your browser to test the endpoints.

Get All Products

  • URL: http://localhost:8080/products
  • Method: GET

Get a Product by ID

  • URL: http://localhost:8080/products/{id}
  • Method: GET

Create a Product

  • URL: http://localhost:8080/products
  • Method: POST
  • Body:
    {
        "id": "1",
        "name": "Product 1",
        "description": "Description 1",
        "price": 10.0
    }
    

Delete a Product

  • URL: http://localhost:8080/products/{id}
  • Method: DELETE

Conclusion

In this tutorial, you have learned how to integrate DynamoDB with a Spring Boot application using Spring Data. We covered:

  • Setting up a Spring Boot project with DynamoDB dependencies.
  • Configuring DynamoDB client in Spring Boot.
  • Defining an entity class and repository.
  • Creating service and controller layers.
  • Running and testing the application using REST endpoints.

By following these steps, you can build scalable and efficient applications using DynamoDB with Spring Boot.


Comments