aws-dynamodb v0.1.0
AWS DynamoDB Client - Crystal 1.16+
Warning: This shard has been almost entirely updated using Claude Opus 4.6 and has not been tested in a production environment yet. Use with caution.
Project Overview
Generic DynamoDB client for Crystal 1.16+. Provides complete AWS DynamoDB operations with optional Lucky Framework integration patterns.
Comparison: Before vs. Now
| Aspect | Original Version | This Version |
|---|---|---|
| Crystal | 0.35.1 (2020) | 1.16+ (2026) |
| JSON | JSON.mapping (deprecated) |
JSON::Serializable |
| Operations | 5 basic | 7 complete + helpers |
| Examples | Basic | Full real-world use case |
| Lucky Integration | No | Yes (example patterns) |
| Docker | No | Yes (Compose + Admin UI) |
| Docs | Basic README | Comprehensive guides |
Core Features
The shard provides:
client.list_tables
client.create_table
client.delete_table
client.put_item
client.get_item
client.update_item
client.query
client.delete_item
Installation
Add to your shard.yml:
dependencies:
aws-dynamodb:
github: MatheusBasso99/aws-dynamodb
version: ~> 0.1.0
Run:
shards install
Quick Start
require "aws-dynamodb"
client = Aws::DynamoDB::Client.new(
region: "us-east-1",
aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
endpoint: ENV["DYNAMODB_ENDPOINT"]?
)
client.put_item(
TableName: "my_table",
Item: {
id: {S: "123"},
name: {S: "John Doe"},
age: {N: 30}
}
)
response = client.get_item(
TableName: "my_table",
Key: {id: {S: "123"}}
)
Example Implementation: Video Progress System
The examples/ directory contains a complete real-world implementation of a Video Progress tracking system. This demonstrates:
- Domain model with DynamoDB serialization
- Repository pattern
- Lucky Framework Actions
- Configuration management
- Testing strategies
Note: This is an example implementation. Copy and adapt it to your specific needs rather than importing it directly.
Example Structure
examples/
├── video_progress_model.cr # Example domain model
├── video_progress_repository.cr # Example repository
├── usage_example.cr # Standalone usage
├── lucky_actions/ # Example Lucky Actions
└── lucky_integration/ # Example configuration
Lucky Framework Integration
Generic Configuration Pattern
Create a configuration module for your project:
# config/dynamo_db.cr
class DynamoDB
Habitat.create do
setting region : String = ENV["AWS_REGION"]? || "us-east-1"
setting access_key_id : String = ENV["AWS_ACCESS_KEY_ID"]? || ""
setting secret_access_key : String = ENV["AWS_SECRET_ACCESS_KEY"]? || ""
setting endpoint : String? = ENV["DYNAMODB_ENDPOINT"]?
end
end
# src/models/dynamo_db.cr
class DynamoDB
Habitat.create do
setting region : String
setting access_key_id : String
setting secret_access_key : String
setting endpoint : String
end
end
Example Action Pattern
class Api::Items::Update < ApiAction
post "/api/items/:id" do
item_id = id
DynamoDBClient.client.update_item(
TableName: "items",
Key: {id: {S: item_id}},
UpdateExpression: "SET #name = :name",
ExpressionAttributeNames: {"#name" => "name"},
ExpressionAttributeValues: {":name" => {S: params.get(:name)}}
)
json({success: true})
end
end
Local Development Setup
docker-compose up -d
cp .env.example .env
crystal examples/setup_dynamodb.cr -- --run
Access DynamoDB Admin UI at http://localhost:8001
Production Deployment
IAM Policy Template
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"dynamodb:GetItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Query",
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem"
],
"Resource": [
"arn:aws:dynamodb:REGION:ACCOUNT_ID:table/YOUR_TABLE",
"arn:aws:dynamodb:REGION:ACCOUNT_ID:table/YOUR_TABLE/index/*"
]
}
]
}
Performance Patterns
Connection Pool
class DynamoDBClientPool
def initialize(@size : Int32 = 10)
@clients = Array(Aws::DynamoDB::Client).new(@size) { create_client }
@index = 0
end
def client : Aws::DynamoDB::Client
@clients[@index % @size].tap { @index += 1 }
end
private def create_client
Aws::DynamoDB::Client.new(region: ENV["AWS_REGION"]? || "us-east-1")
end
end
Redis Caching Pattern
class CachedRepository(T)
def initialize(@client : Aws::DynamoDB::Client, @redis : Redis, @table : String)
end
def find(key : Hash) : T?
cache_key = "#{@table}:#{key.to_json}"
if cached = @redis.get(cache_key)
return T.from_json(cached)
end
response = @client.get_item(TableName: @table, Key: key)
if item = response[:Item]
result = T.from_dynamodb(item)
@redis.setex(cache_key, 300, result.to_json)
result
end
end
end
Monitoring
Key CloudWatch Metrics:
ConsumedReadCapacityUnitsConsumedWriteCapacityUnitsThrottledRequestsUserErrorsSuccessfulRequestLatency
Testing
Run the test suite:
crystal spec
The test suite includes:
- Client operation tests
- Type serialization tests
- Example implementation tests (VideoProgress)
Roadmap
- Batch operations (
BatchGetItem,BatchWriteItem) - Global Secondary Index (GSI) support
- DynamoDB Streams integration
- Circuit breaker pattern
- Prometheus metrics exporter
Contributing
Contributions are welcome! Please ensure:
- Tests pass
- Code follows Crystal style guide
- Examples remain generic and reusable
License
MIT
aws-dynamodb
- 0
- 0
- 0
- 0
- 3
- about 3 hours ago
- February 13, 2026
Sat, 14 Feb 2026 21:04:37 GMT