Amazon DynamoDB Batch Operations with Spring Boot - Read, Write & Delete


To implement batch operations (read, write, and delete) in Amazon DynamoDB using Spring Boot, you'll typically leverage the AWS SDK for Java and its DynamoDB client. Below is a guide to achieve this functionality:


1. Setup DynamoDB in Spring Boot

Add Dependencies

Add the following dependencies to your pom.xml if you're using Maven:

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>dynamodb</artifactId>
    <version>2.20.1</version> <!-- Use the latest version -->
</dependency>

AWS Credentials Configuration

Set up your AWS credentials in:

  • Environment Variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), or
  • A configuration file (e.g., ~/.aws/credentials), or
  • Directly in your application properties (not recommended for production):
    aws.accessKeyId=your-access-key
    aws.secretKey=your-secret-key
    aws.region=us-west-2

Create a DynamoDB Configuration Bean

@Configuration
public class DynamoDBConfig {

    @Bean
    public DynamoDbClient dynamoDbClient() {
        return DynamoDbClient.builder()
                .region(Region.US_WEST_2) // Replace with your region
                .build();
    }
}

2. Batch Operations in DynamoDB

DynamoDB supports batch operations for:

  • Writing items: batchWriteItem
  • Reading items: batchGetItem
  • Deleting items: Part of batchWriteItem

Batch Write (Write & Delete)

@Service
public class DynamoDBBatchService {

    private final DynamoDbClient dynamoDbClient;

    public DynamoDBBatchService(DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    public void batchWrite(List<PutRequest> putRequests, List<DeleteRequest> deleteRequests, String tableName) {
        Map<String, List<WriteRequest>> requestItems = new HashMap<>();

        // Add Put Requests
        if (!putRequests.isEmpty()) {
            List<WriteRequest> writes = putRequests.stream()
                    .map(req -> WriteRequest.builder().putRequest(req).build())
                    .toList();
            requestItems.put(tableName, writes);
        }

        // Add Delete Requests
        if (!deleteRequests.isEmpty()) {
            List<WriteRequest> deletes = deleteRequests.stream()
                    .map(req -> WriteRequest.builder().deleteRequest(req).build())
                    .toList();
            requestItems.put(tableName, deletes);
        }

        BatchWriteItemRequest batchWriteItemRequest = BatchWriteItemRequest.builder()
                .requestItems(requestItems)
                .build();

        BatchWriteItemResponse response = dynamoDbClient.batchWriteItem(batchWriteItemRequest);
        if (!response.unprocessedItems().isEmpty()) {
            System.err.println("Some items were not processed: " + response.unprocessedItems());
        }
    }
}

Batch Read

public Map<String, List<Map<String, AttributeValue>>> batchRead(List<Map<String, AttributeValue>> keys, String tableName) {
    Map<String, KeysAndAttributes> requestItems = new HashMap<>();
    requestItems.put(tableName, KeysAndAttributes.builder().keys(keys).build());

    BatchGetItemRequest batchGetItemRequest = BatchGetItemRequest.builder()
            .requestItems(requestItems)
            .build();

    BatchGetItemResponse response = dynamoDbClient.batchGetItem(batchGetItemRequest);
    return response.responses();
}

3. DTOs for Requests

Define DTOs for representing the items for readability and maintainability.

PutRequest DTO

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Item {
    private String id;
    private String name;
    private String description;

    public Map<String, AttributeValue> toAttributeMap() {
        return Map.of(
                "id", AttributeValue.builder().s(id).build(),
                "name", AttributeValue.builder().s(name).build(),
                "description", AttributeValue.builder().s(description).build()
        );
    }
}

DeleteRequest Example

public DeleteRequest createDeleteRequest(String id) {
    return DeleteRequest.builder()
            .key(Map.of("id", AttributeValue.builder().s(id).build()))
            .build();
}

4. Sample Controller

Create a REST controller to expose the batch operations:

@RestController
@RequestMapping("/dynamodb")
public class DynamoDBController {

    private final DynamoDBBatchService batchService;

    public DynamoDBController(DynamoDBBatchService batchService) {
        this.batchService = batchService;
    }

    @PostMapping("/batch-write")
    public ResponseEntity<String> batchWrite(@RequestBody List<Item> items) {
        List<PutRequest> putRequests = items.stream()
                .map(item -> PutRequest.builder().item(item.toAttributeMap()).build())
                .toList();

        batchService.batchWrite(putRequests, List.of(), "YourTableName");
        return ResponseEntity.ok("Batch write completed");
    }

    @PostMapping("/batch-delete")
    public ResponseEntity<String> batchDelete(@RequestBody List<String> ids) {
        List<DeleteRequest> deleteRequests = ids.stream()
                .map(id -> DeleteRequest.builder().key(Map.of("id", AttributeValue.builder().s(id).build())).build())
                .toList();

        batchService.batchWrite(List.of(), deleteRequests, "YourTableName");
        return ResponseEntity.ok("Batch delete completed");
    }

    @PostMapping("/batch-read")
    public ResponseEntity<Map<String, List<Map<String, AttributeValue>>>> batchRead(@RequestBody List<String> ids) {
        List<Map<String, AttributeValue>> keys = ids.stream()
                .map(id -> Map.of("id", AttributeValue.builder().s(id).build()))
                .toList();

        Map<String, List<Map<String, AttributeValue>>> result = batchService.batchRead(keys, "YourTableName");
        return ResponseEntity.ok(result);
    }
}

5. Testing the API

You can test these endpoints using Postman or cURL:

Batch Write Example:

POST /dynamodb/batch-write
[
    {"id": "1", "name": "Item1", "description": "Description1"},
    {"id": "2", "name": "Item2", "description": "Description2"}
]

Batch Delete Example:

POST /dynamodb/batch-delete
["1", "2"]

Batch Read Example:

POST /dynamodb/batch-read
["1", "2"]

Comments

Popular posts from this blog

Spring Boot OpenAI Integration: Step-by-Step Guide

Orchestration-Based Saga Architecture and Spring Boot Microservices Implementation Guide

Spring Boot 3 + Angular 15 + Material - Full Stack CRUD Application Example