Files
Daniel Romischer 9f07b0c6f9 Complete tasks 3.2-3.3: Data models and DynamoDB table schemas
- Defined all 8 data models (Page, Widget, Bookmark, Note, TagAssociation, Group, Share, Preferences)
- Implemented DynamoDB table creation for all tables with proper schemas
- Added GSIs for efficient querying (UserBookmarksIndex, UserNotesIndex, TagItemsIndex, UserSharesIndex)
- Comprehensive test coverage for all table schemas
- Updated init-db command to create all tables
2026-02-18 22:55:06 -05:00
..

DynamoDB Storage Service

This package provides an enhanced DynamoDB client wrapper with the following features:

Features

1. Connection Pooling

The client uses the AWS SDK's default HTTP client which includes connection pooling automatically. This ensures efficient reuse of TCP connections to DynamoDB.

2. Retry Logic with Exponential Backoff

The client is configured with automatic retry logic:

  • Max Attempts: 5 retries
  • Max Backoff: 20 seconds
  • Strategy: Exponential backoff with jitter to prevent thundering herd

This handles transient failures gracefully and improves reliability.

3. Transaction Support

The TransactWriteItems method provides ACID transaction support for multiple write operations:

err := client.TransactWriteItems(ctx, &dynamodb.TransactWriteItemsInput{
    TransactItems: []types.TransactWriteItem{
        {
            Put: &types.Put{
                TableName: aws.String("MyTable"),
                Item: map[string]types.AttributeValue{
                    "id": &types.AttributeValueMemberS{Value: "item1"},
                },
            },
        },
        // More items...
    },
})

4. Batch Operations

The client provides batch read and write operations with automatic retry of unprocessed items:

BatchGetItems

Retrieves multiple items in a single request:

output, err := client.BatchGetItems(ctx, &dynamodb.BatchGetItemInput{
    RequestItems: map[string]types.KeysAndAttributes{
        "MyTable": {
            Keys: []map[string]types.AttributeValue{
                {"id": &types.AttributeValueMemberS{Value: "item1"}},
                {"id": &types.AttributeValueMemberS{Value: "item2"}},
            },
        },
    },
})

BatchWriteItems

Writes multiple items in a single request:

err := client.BatchWriteItems(ctx, &dynamodb.BatchWriteItemInput{
    RequestItems: map[string][]types.WriteRequest{
        "MyTable": {
            {
                PutRequest: &types.PutRequest{
                    Item: map[string]types.AttributeValue{
                        "id": &types.AttributeValueMemberS{Value: "item1"},
                    },
                },
            },
        },
    },
})

Both batch operations automatically handle unprocessed items with exponential backoff retry logic.

Standard Operations

The client also provides wrapped versions of standard DynamoDB operations with automatic retry:

  • PutItem - Put a single item
  • GetItem - Get a single item
  • UpdateItem - Update a single item
  • DeleteItem - Delete a single item
  • Query - Query items

Usage

Creating a Client

ctx := context.Background()
client, err := storage.NewDynamoDBClient(ctx, "http://localhost:8000")
if err != nil {
    log.Fatal(err)
}

For production (AWS DynamoDB), pass an empty string for the endpoint:

client, err := storage.NewDynamoDBClient(ctx, "")

Testing

The package includes comprehensive tests that can be run against DynamoDB Local:

  1. Start DynamoDB Local:
docker-compose up -d
  1. Run tests:
go test -v ./internal/storage

Tests will automatically skip if DynamoDB is not available.

Requirements Addressed

This implementation addresses the following requirements from the spec:

  • Requirement 8.1: Immediate persistence of all changes
  • Requirement 8.8: Efficient scaling for 10,000+ items per user
  • Design requirement: Retry logic with exponential backoff
  • Design requirement: Transaction support for atomic operations
  • Design requirement: Batch operations for efficient bulk reads/writes
  • Design requirement: Connection pooling for performance