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

Fos Http Cache Cloudfront Laravel Package

jean-beru/fos-http-cache-cloudfront

CloudFront proxy implementation for FOSHttpCache. Create a CloudFrontClient, configure your distribution ID, then purge/invalidate specific URLs or patterns (e.g., /assets/*) and flush requests. Supports caller reference generators to avoid duplicate invalidations.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install Dependencies:
    composer require jean-beru/fos-http-cache-cloudfront async-aws/cloudfront
    
  2. Configure AWS SDK: Ensure AWS credentials are available via environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) or Laravel’s AWS config (config/aws.php).
  3. Initialize the Proxy:
    use Aws\CloudFront\CloudFrontClient;
    use JeanBeru\HttpCacheCloudFront\Proxy\CloudFront;
    
    $client = new CloudFrontClient([
        'region'  => env('AWS_REGION'),
        'version' => 'latest',
    ]);
    
    $proxy = new CloudFront(
        client: $client,
        options: [
            'distribution_id' => env('CLOUDFRONT_DISTRIBUTION_ID'),
        ]
    );
    
  4. First Use Case: Purge a single URL (e.g., after content update):
    $proxy->purge('/home')->flush();
    

Where to Look First

  • README.md: Focus on the Usage section for core patterns.
  • CallerReference/: Explore generator classes (e.g., UniqIdCallerReferenceGenerator) to customize deduplication logic.
  • Tests: Review tests/ for edge cases (e.g., invalidation failures, rate limiting).

Implementation Patterns

Core Workflows

1. Cache Invalidation

  • Single URL Purge:
    $proxy->purge('/path/to/resource')->flush();
    
  • Batch Invalidation:
    $proxy->purge('/assets/*')->purge('/images/*')->flush();
    
  • Dynamic Paths: Use Laravel’s route helpers to generate paths:
    $proxy->purge(route('product.show', $id))->flush();
    

2. Cache Warmup

Pre-load critical paths during deployment:

$proxy->warmup('/home')->warmup('/products')->flush();

3. Integration with Laravel Events

Trigger purges on model updates:

// app/Providers/EventServiceProvider.php
public function boot()
{
    ProductUpdated::listen(function ($product) {
        app('cloudfront.proxy')->purge(route('product.show', $product))->flush();
    });
}

4. Hybrid Caching

Combine with Laravel’s cache drivers:

// Cache in Redis, invalidate in CloudFront
Cache::put('key', $data, now()->addMinutes(5));
app('cloudfront.proxy')->purge('/cached-data')->flush();

Laravel-Specific Patterns

Service Provider Binding

// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->singleton('cloudfront.proxy', function ($app) {
        $client = new CloudFrontClient($app['config']['aws.cloudfront']);
        return new CloudFront($client, [
            'distribution_id' => $app['config']['services.cloudfront.distribution_id'],
        ]);
    });
}

Facade Extension (Optional)

Create a CloudFront facade for cleaner syntax:

// app/Facades/CloudFront.php
public static function purge(string $path): self
{
    return static::getFacadeRoot()->purge($path);
}

Command-Line Invalidation

Add an Artisan command for manual purges:

// app/Console/Commands/PurgeCloudFront.php
public function handle()
{
    $proxy = app('cloudfront.proxy');
    $proxy->purge($this->argument('path'))->flush();
    $this->info('Purged: '.$this->argument('path'));
}

Gotchas and Tips

Pitfalls

  1. AWS SDK Conflicts:

    • Issue: Mixing async-aws/cloudfront with aws/aws-sdk-php (v2) may cause autoloading errors.
    • Fix: Enforce SDK version in composer.json:
      "require": {
          "async-aws/cloudfront": "^3.0"
      },
      "conflict": {
          "aws/aws-sdk-php": "*"
      }
      
  2. Duplicate Invalidation Errors:

    • Issue: AWS throws FOS\HttpCache\Exception\ProxyResponseException if the same caller_reference is reused.
    • Fix: Use a custom CallerReferenceGenerator (e.g., DateCallerReferenceGenerator) for time-based uniqueness:
      $proxy = new CloudFront($client, [
          'distribution_id' => 'XYZ123',
          'caller_reference_generator' => new DateCallerReferenceGenerator('YmdHis'),
      ]);
      
  3. CloudFront Distribution Mismatch:

    • Issue: Invalidating paths for the wrong distribution (e.g., staging vs. production).
    • Fix: Validate distribution_id in config and use environment-specific values.
  4. TTL Misconfiguration:

    • Issue: CloudFront’s default TTL (24h) may conflict with Laravel’s cache TTL.
    • Fix: Adjust DefaultCacheBehavior in CloudFront or use Cache-Control headers to override TTLs.
  5. Rate Limiting:

    • Issue: AWS CloudFront API limits to 1,000 requests/second (shared across all AWS services).
    • Fix: Batch purges and implement exponential backoff:
      $proxy->purge('/path1')->purge('/path2')->flush();
      

Debugging Tips

  1. Enable AWS SDK Debugging:

    $client = new CloudFrontClient([
        'debug' => true,
        'logger' => new \Aws\Handler\Log\LogHandler(new \Monolog\Logger('CloudFront')),
    ]);
    
  2. Check CloudFront Logs:

    • Use AWS CloudTrail to audit invalidation requests.
    • Monitor InvalidationList in the CloudFront console for failures.
  3. Test Locally:

    • Mock the AWS client in tests:
      $mock = Mockery::mock(CloudFrontClient::class);
      $mock->shouldReceive('createInvalidation')->andReturn(new Invalidation(['status' => 'InProgress']));
      

Extension Points

  1. Custom Caller Reference: Implement CallerReferenceGenerator for business-specific deduplication:

    class OrderIdCallerReferenceGenerator implements CallerReferenceGenerator
    {
        public function generate(): string
        {
            return 'order-'.Order::latest()->first()->id;
        }
    }
    
  2. Pre/Post-Flush Hooks: Extend the CloudFront class to add callbacks:

    class ExtendedCloudFront extends CloudFront
    {
        public function flush(): self
        {
            $this->logPurgeRequest();
            parent::flush();
            $this->notifySlack();
            return $this;
        }
    }
    
  3. Multi-Distribution Support: Override the proxy to handle multiple distributions:

    class MultiDistributionProxy
    {
        public function __construct(private array $proxies) {}
    
        public function purge(string $path): self
        {
            foreach ($this->proxies as $proxy) {
                $proxy->purge($path);
            }
            return $this;
        }
    }
    

Configuration Quirks

  1. AWS Region: Ensure the AWS SDK region matches your CloudFront distribution’s edge location (e.g., us-east-1 for global distributions).

  2. IAM Permissions: The IAM user/role must have:

    {
        "Effect": "Allow",
        "Action": [
            "cloudfront:CreateInvalidation",
            "cloudfront:GetInvalidation"
        ],
        "Resource": "arn:aws:cloudfront::DISTRIBUTION_ID"
    }
    
  3. Path Patterns: CloudFront invalidation paths must match the distribution’s CacheBehaviors. For example:

    • /assets/* works if the behavior is configured for assets.*.
    • /api/* requires a separate behavior for API paths.
  4. Environment Variables: Avoid hardcoding credentials. Use Laravel’s .env:

    AWS_ACCESS_KEY_ID=your_key
    AWS_SECRET_ACCESS_KEY=your_secret
    CLOUDFRONT_DISTRIBUTION_ID=XYZ123
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky