Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dynamodb Laravel Package

baopham/dynamodb

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require baopham/dynamodb
    

    Publish the config:

    php artisan vendor:publish --provider="Baopham\LaravelDynamoDB\LaravelDynamoDBServiceProvider"
    
  2. 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'),
            ],
        ],
    ],
    
  3. 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
    }
    
  4. First Use Case: Fetch a record:

    $user = User::find('user123');
    

Implementation Patterns

Eloquent-Like Workflows

  • 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']);
    

Composite Keys

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']);

Pagination

$users = User::paginate(10); // Uses DynamoDB's Scan with limit/offset

Batch Operations

// Batch write (create/update/delete)
User::batchWrite([
    ['put' => ['user_id' => 'user1', 'data' => ['name' => 'Alice']]],
    ['delete' => ['user_id' => 'user2']],
]);

Transactions

User::transaction(function ($transaction) {
    $transaction->put('user1', ['name' => 'Alice']);
    $transaction->update('user2', ['status' => 'active']);
});

Gotchas and Tips

Pitfalls

  1. Primary Key Handling:

    • DynamoDB requires a primary key (hash or composite). Forgetting to define $primaryKey will cause errors.
    • Composite keys must be an array: protected $primaryKey = ['hash_key', 'range_key'];.
  2. Async Operations:

    • Async methods (updateAsync, saveAsync) return immediately but don’t block. Use callbacks for results:
      User::updateAsync(['status' => 'inactive'], ['user_id' => 'user123'], function ($result) {
          // Handle result
      });
      
  3. Pagination Limitations:

    • DynamoDB’s Scan (used for all()) is slower than Query. Prefer Query with a key condition if possible.
    • Avoid deep pagination (e.g., offset > 1000) due to DynamoDB’s 1MB response size limit.
  4. Attribute Mapping:

    • DynamoDB maps attributes to JSON. Nested objects/arrays are stored as-is, but ensure your model’s $casts property handles type conversion:
      protected $casts = [
          'metadata' => 'array',
          'created_at' => 'datetime',
      ];
      
  5. Conditional Writes:

    • DynamoDB requires explicit conditions for updates/deletes. Use where or conditions:
      // Fails if 'status' is not 'active'
      User::update(['status' => 'inactive'], ['user_id' => 'user123'])
          ->where('status', 'active');
      

Debugging Tips

  1. Enable AWS SDK Debugging: Add to config/dynamodb.php:

    'debug' => env('APP_DEBUG', false),
    

    Check logs for DynamoDB API calls.

  2. Check Table Schema: Ensure your table’s primary key matches the model’s $primaryKey. Mismatches cause find() to fail silently.

  3. Throttling: DynamoDB throttles requests (e.g., ProvisionedThroughputExceeded). Handle exceptions:

    try {
        User::find('user123');
    } catch (\Aws\DynamoDb\Exception\ProvisionedThroughputExceededException $e) {
        // Retry or notify admin
    }
    

Extension Points

  1. 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;
    
  2. Event Hooks: Listen to DynamoDB events (e.g., retrieved, saved) via Laravel’s event system:

    User::retrieved(function ($model) {
        // Log or transform data
    });
    
  3. 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;
    }
    

Performance Tips

  1. Use Query Over Scan: Replace User::all() with User::where('status', 'active')->get() to leverage DynamoDB’s Query (faster and cheaper).

  2. Batch Reads/Writes: Use batchWrite() or query()->batch() to reduce API calls:

    User::query()->batch(['user1', 'user2', 'user3'])->get();
    
  3. Projection Expressions: Limit returned attributes to reduce payload size:

    $users = User::where('status', 'active')
                ->select(['user_id', 'name'])
                ->get();
    
  4. Exponential Backoff: Implement retry logic for throttled requests using AWS SDK’s RetryHandler.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium