Installation:
composer require baopham/dynamodb
Publish the config:
php artisan vendor:publish --provider="Baopham\LaravelDynamoDB\LaravelDynamoDBServiceProvider"
Configure DynamoDB:
Edit config/dynamodb.php with your AWS credentials, region, and table name:
'connections' => [
'default' => [
'region' => 'us-west-2',
'table' => 'your_table_name',
'credentials' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
],
],
],
Define a Model:
Extend Baopham\LaravelDynamoDB\Eloquent\Model:
use Baopham\LaravelDynamoDB\Eloquent\Model;
class User extends Model
{
protected $table = 'users';
protected $primaryKey = 'user_id'; // Required for DynamoDB
public $incrementing = false; // DynamoDB doesn't auto-increment
}
First Use Case: Fetch a record:
$user = User::find('user123');
CRUD Operations:
// Create
$user = new User(['user_id' => 'user123', 'name' => 'John']);
$user->save();
// Read
$user = User::find('user123');
// Update
$user->name = 'Jane';
$user->save();
// Delete
$user->delete();
Querying with Conditions:
// Simple condition
$users = User::where('status', 'active')->get();
// Complex conditions (DynamoDB expressions)
$users = User::where('age', '>', 25)
->where('status', 'active')
->get();
Async Operations:
User::updateAsync(['status' => 'inactive'], ['user_id' => 'user123']);
Define both hash and range keys in your model:
class Order extends Model
{
protected $table = 'orders';
protected $primaryKey = ['user_id', 'order_id']; // Composite key
public $incrementing = false;
}
Query with both keys:
$order = Order::find(['user123', 'order456']);
$users = User::paginate(10); // Uses DynamoDB's Scan with limit/offset
// Batch write (create/update/delete)
User::batchWrite([
['put' => ['user_id' => 'user1', 'data' => ['name' => 'Alice']]],
['delete' => ['user_id' => 'user2']],
]);
User::transaction(function ($transaction) {
$transaction->put('user1', ['name' => 'Alice']);
$transaction->update('user2', ['status' => 'active']);
});
Primary Key Handling:
$primaryKey will cause errors.protected $primaryKey = ['hash_key', 'range_key'];.Async Operations:
updateAsync, saveAsync) return immediately but don’t block. Use callbacks for results:
User::updateAsync(['status' => 'inactive'], ['user_id' => 'user123'], function ($result) {
// Handle result
});
Pagination Limitations:
Scan (used for all()) is slower than Query. Prefer Query with a key condition if possible.offset > 1000) due to DynamoDB’s 1MB response size limit.Attribute Mapping:
$casts property handles type conversion:
protected $casts = [
'metadata' => 'array',
'created_at' => 'datetime',
];
Conditional Writes:
where or conditions:
// Fails if 'status' is not 'active'
User::update(['status' => 'inactive'], ['user_id' => 'user123'])
->where('status', 'active');
Enable AWS SDK Debugging:
Add to config/dynamodb.php:
'debug' => env('APP_DEBUG', false),
Check logs for DynamoDB API calls.
Check Table Schema:
Ensure your table’s primary key matches the model’s $primaryKey. Mismatches cause find() to fail silently.
Throttling:
DynamoDB throttles requests (e.g., ProvisionedThroughputExceeded). Handle exceptions:
try {
User::find('user123');
} catch (\Aws\DynamoDb\Exception\ProvisionedThroughputExceededException $e) {
// Retry or notify admin
}
Custom Query Builders:
Extend Baopham\LaravelDynamoDB\Eloquent\Builder to add custom methods:
class CustomBuilder extends \Baopham\LaravelDynamoDB\Eloquent\Builder
{
public function activeUsers()
{
return $this->where('status', 'active');
}
}
Override the builder in your model:
protected $builder = CustomBuilder::class;
Event Hooks:
Listen to DynamoDB events (e.g., retrieved, saved) via Laravel’s event system:
User::retrieved(function ($model) {
// Log or transform data
});
Custom Attributes:
Override getAttributes() or setAttributes() in your model to transform data before/after storage:
public function getAttributes()
{
$attrs = parent::getAttributes();
$attrs['processed_at'] = now()->toDateTimeString();
return $attrs;
}
Use Query Over Scan:
Replace User::all() with User::where('status', 'active')->get() to leverage DynamoDB’s Query (faster and cheaper).
Batch Reads/Writes:
Use batchWrite() or query()->batch() to reduce API calls:
User::query()->batch(['user1', 'user2', 'user3'])->get();
Projection Expressions: Limit returned attributes to reduce payload size:
$users = User::where('status', 'active')
->select(['user_id', 'name'])
->get();
Exponential Backoff:
Implement retry logic for throttled requests using AWS SDK’s RetryHandler.
How can I help you explore Laravel packages today?