Skip to content

Enable DynamoDbChatStorage customization for local development and testing #368

Description

@yilinglu

Problem Description

Currently, DynamoDbChatStorage creates its DynamoDB client internally with no way to customize the configuration. This makes it difficult to use in common scenarios:

  1. Local Development: Cannot use DynamoDB Local without duplicating the entire class
  2. Testing: Cannot inject mock clients for unit tests
  3. Custom Endpoints: Cannot use DynamoDB-compatible services (LocalStack, ScyllaDB Alternator)
  4. Special Configurations: Cannot apply custom retry strategies or other client configurations

Current Workarounds (Not Ideal)

Users currently have to either:

  • Fork and modify the source code
  • Duplicate the entire DynamoDbChatStorage implementation (~200+ lines of code)
  • Use type casting hacks like (this as any).docClient = customClient

Proposed Solution

Add a protected method to allow subclasses to customize the DynamoDB Document Client:

protected setDocClient(client: DynamoDBDocumentClient): void {
  this.docClient = client;
}

This would enable clean inheritance patterns:

class LocalDynamoDbChatStorage extends DynamoDbChatStorage {
  constructor(tableName: string, region: string, endpoint: string) {
    super(tableName, region);
    
    const client = new DynamoDBClient({
      region,
      endpoint,
      credentials: { accessKeyId: 'dummy', secretAccessKey: 'dummy' }
    });
    
    this.setDocClient(DynamoDBDocumentClient.from(client));
  }
}

Benefits

  • Non-breaking change: Existing code continues to work unchanged
  • Minimal code: Subclasses only need to override constructor
  • Type-safe: No type casting required
  • Flexible: Enables all customization scenarios

Use Cases

  1. Local Development

    const storage = new LocalDynamoDbChatStorage('table', 'us-east-1', 'http://localhost:8000');
  2. Testing

    const mockClient = createMockDynamoDBClient();
    class TestStorage extends DynamoDbChatStorage {
      constructor() {
        super('test-table', 'us-east-1');
        this.setDocClient(mockClient);
      }
    }
  3. Custom Services

    const storage = new CustomEndpointStorage('table', 'us-east-1', 'http://localstack:4566');

I have a PR ready with implementation and tests for this enhancement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions