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

Guzzle Cache Middleware Laravel Package

kevinrob/guzzle-cache-middleware

RFC 7234–compliant HTTP cache middleware for Guzzle 6+ using a HandlerStack. Improve API call performance with transparent caching. Supports PSR-7 and multiple storages: Laravel cache, Flysystem, PSR-6/16, and WordPress object cache.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • HTTP Caching Layer: The package provides a RFC 7234-compliant HTTP caching middleware for Guzzle, making it a natural fit for Laravel applications where API responses (e.g., third-party services, external APIs) are frequently called but rarely change.
  • PSR-7 & PSR-16/PSR-6 Compliance: Aligns with Laravel’s ecosystem (e.g., Cache facade, Psr\Cache interfaces), reducing integration friction.
  • Middleware-Based Design: Leverages Guzzle’s HandlerStack, enabling non-intrusive caching without modifying core HTTP logic.
  • Strategy Patterns: Supports private/public/shared/greedy/delegating caching strategies, allowing granular control over caching behavior per API endpoint or use case.

Integration Feasibility

  • Laravel Native Support: Direct integration with Laravel’s Cache facade (Redis, Memcached, database, etc.) via LaravelCacheStorage.
  • Flysystem/PSR-6/PSR-16: Works with Laravel’s filesystem (e.g., Storage::disk()) or third-party cache adapters (e.g., cache/simple-cache-bridge).
  • Guzzle 6+ Compatibility: Laravel’s built-in HttpClient (Guzzle 7+) is backward-compatible, though minor adjustments may be needed for Guzzle 7+ features (e.g., sink option handling).
  • Service Provider Pattern: Can be bootstrapped in Laravel’s AppServiceProvider or as a dedicated CacheServiceProvider for centralized configuration.

Technical Risk

Risk Area Mitigation Strategy
Cache Invalidation Use CacheMiddleware::delete() or leverage Laravel’s cache tags for bulk invalidation.
Binary Data Corruption Fixed in v7.0.0; ensure package is ≥v7.0.0.
TTL Misconfiguration Defaults to RFC 7234; override via GreedyCacheStrategy or Cache-Control headers.
Thread Safety PSR-6/PSR-16 storage backends (e.g., Redis) are thread-safe; avoid shared-memory issues.
Guzzle 7+ Breaking Changes Test sink option handling (fixed in v8.0.0-RC1) and stream rewinding.
DST/Timezone Bugs Fixed in v8.0.0-RC1; use PSR-20 Clock for deterministic time management.

Key Questions

  1. Caching Granularity:
    • Should caching be global (all API calls) or selective (e.g., only for twitter.com)?
    • Solution: Use DelegatingCacheStrategy with custom RequestMatcher interfaces.
  2. Storage Backend:
    • Redis (low-latency), database (durability), or filesystem (simplicity)?
    • Recommendation: Benchmark with Laravel’s default cache driver.
  3. Stale-While-Revalidate:
    • Should stale responses be served while revalidating in the background?
    • Default: Enabled for max-age and s-maxage headers.
  4. Cache Key Collisions:
    • How to handle Vary headers (e.g., Accept-Encoding, User-Agent)?
    • Solution: Package respects Vary headers by default.
  5. Monitoring:
    • How to track cache hit/miss ratios and TTL effectiveness?
    • Approach: Log middleware events or integrate with Laravel’s events system.

Integration Approach

Stack Fit

  • Laravel Ecosystem:
    • Guzzle 7+: Laravel’s HttpClient (v1.0+) is compatible; wrap it with CacheMiddleware.
    • Cache Backends: Redis (recommended for production), database, or filesystem.
    • PSR Standards: Leverage Psr\Cache interfaces for portability.
  • Alternatives:
    • Symfony HTTP Client: If using Symfony components, the same middleware applies.
    • WordPress: Supported natively via WordPressObjectCacheStorage.

Migration Path

  1. Phase 1: Proof of Concept
    • Add middleware to a single API client (e.g., TwitterClient).
    • Test with PrivateCacheStrategy + Redis.
    • Validate cache hit ratio and latency improvements.
  2. Phase 2: Selective Caching
    • Implement DelegatingCacheStrategy to exclude sensitive endpoints (e.g., auth tokens).
    • Example:
      $strategy = new DelegatingCacheStrategy(new NullCacheStrategy());
      $strategy->registerRequestMatcher(
          new AuthEndpointMatcher(),
          new NullCacheStrategy() // Bypass cache for auth endpoints
      );
      
  3. Phase 3: Global Rollout
    • Replace all HttpClient instances with cached versions.
    • Configure Laravel’s Cache facade as the default storage.
  4. Phase 4: Monitoring
    • Add middleware logging (e.g., Monolog channel) to track cache metrics.
    • Set up Laravel Horizon jobs to purge stale cache entries.

Compatibility

Component Compatibility Notes
Laravel 10+ Fully supported (tested up to v8.0.0-RC1).
Guzzle 7+ Minor adjustments needed for sink option (fixed in v8.0.0-RC1).
Redis/Predis PSR-6 adapter (cache/redis-adapter) recommended.
Database Cache Use database driver with Psr6CacheStorage.
Filesystem Cache Works with Storage::disk('cache') via FlysystemStorage.
WordPress Native support via WordPressObjectCacheStorage.

Sequencing

  1. Configure Cache Backend:
    • Update .env:
      CACHE_DRIVER=redis
      
  2. Register Middleware:
    • In AppServiceProvider:
      public function boot()
      {
          $stack = HandlerStack::create();
          $stack->push(
              new CacheMiddleware(
                  new PrivateCacheStrategy(
                      new LaravelCacheStorage(Cache::store())
                  )
              ),
              'cache'
          );
          $this->app->singleton(GuzzleHttp\Client::class, fn() => new Client(['handler' => $stack]));
      }
      
  3. Test Selective Caching:
    • Use DelegatingCacheStrategy for endpoints requiring no caching.
  4. Optimize TTLs:
    • Adjust max-age headers or use GreedyCacheStrategy for static APIs.
  5. Add Invalidation Logic:
    • Implement CacheMiddleware::delete() in event listeners (e.g., CacheTaggedEvent).

Operational Impact

Maintenance

  • Dependency Updates:
    • Monitor for Guzzle 7+ changes (e.g., sink option).
    • Upgrade to ≥v8.0.0 for PHP 8.5 support and DST fixes.
  • Cache Schema:
    • No database migrations needed for Redis/filesystem; database cache may require table updates.
  • Logging:
    • Add middleware logging to debug cache misses/hits:
      $stack->push(
          TapMiddleware::tap(fn(Transfer $transfer) => logger()->debug(
              'Cache hit/miss', ['request' => $transfer->getRequest()->getUri()]
          )),
          'logging'
      );
      

Support

  • Troubleshooting:
    • Cache Stale Data: Use CacheMiddleware::delete() or Cache::forget().
    • Corrupted Entries: Fixed in v7.0.0; ensure storage backend handles serialization.
    • TTL Issues: Verify Cache-Control headers or use GreedyCacheStrategy.
  • Documentation:
    • Maintain a CACHING.md in Laravel’s docs with:
      • Cache strategy examples.
      • Invalidation procedures.
      • Performance benchmarks.

Scaling

  • Horizontal Scaling:
    • Redis or distributed cache (e.g., Memcached) required for multi-server setups.
    • Avoid filesystem cache in clustered environments.
  • Cold Starts:
    • First request to a cached endpoint may be slower; mitigate with:
      • Pre-warming: Cache critical endpoints at app startup.
      • Greedy Caching: Force TTL for static APIs.
  • Memory Usage:
    • Monitor Redis memory with Laravel Redis tools.
    • Use Cache::rememberForever() sparingly for large responses.

Failure Modes

Failure Scenario Impact Mitigation Strategy
Cache Backend Down Cache misses → increased latency Fallback to NullCacheStrategy or disable caching gracefully.
**Corrupted
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.
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
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope