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

Http Cache Laravel Package

api-platform/http-cache

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require api-platform/http-cache
    
  2. Basic Configuration Register the HttpCache middleware in app/Http/Kernel.php:

    protected $middlewareGroups = [
        'api' => [
            // ...
            \ApiPlatform\HttpCache\Middleware\CacheMiddleware::class,
        ],
    ];
    
  3. First Use Case Enable caching for a single API resource by adding the Cache attribute to your entity:

    use ApiPlatform\Core\Annotation\Cache;
    
    #[Cache(maxAge: 3600)]
    class Book {}
    

    Now, API responses for Book will be cached for 1 hour.


Implementation Patterns

Common Workflows

  1. Entity-Level Caching Use the #[Cache] attribute to define cache behavior per resource:

    #[Cache(maxAge: 60, public: true)]
    class Product {}
    
    • maxAge: Cache lifetime in seconds (default: 0 = no caching).
    • public: Allow caching by proxies/CDNs (default: false).
  2. Collection vs. Item Caching Differentiate between collection (/api/books) and item (/api/books/1) caching:

    #[Cache(maxAge: 300, public: true)]
    #[ApiResource(collectionOperations: ['get'], itemOperations: ['get'])]
    class Book {}
    
  3. Dynamic Cache Keys Override the cache key logic for complex scenarios:

    use ApiPlatform\Core\Annotation\Cache;
    use ApiPlatform\HttpCache\CacheKeyGeneratorInterface;
    
    #[Cache(keyGenerator: MyCustomCacheKeyGenerator::class)]
    class User {}
    
  4. Integration with API Platform Combine with #[ApiResource] for seamless caching of serialized data:

    #[ApiResource]
    #[Cache(maxAge: 1800)]
    class Article {}
    
  5. Cache Invalidation Manually invalidate cache for a resource after updates:

    use ApiPlatform\HttpCache\CacheInvalidatorInterface;
    
    public function __construct(private CacheInvalidatorInterface $cacheInvalidator) {}
    
    public function update(Article $article, UpdateArticleDto $data): Article {
        $article = $this->updateEntity($article, $data);
        $this->cacheInvalidator->invalidate($article);
        return $article;
    }
    

Integration Tips

  • Symfony Cache Component The package relies on Symfony’s Cache component. Configure it in config/packages/framework.yaml:

    framework:
        cache:
            app: cache.adapter.redis
    
  • Varnish/Nginx Integration For public: true caches, ensure your web server is configured to honor Cache-Control headers:

    location /api {
        proxy_cache my_cache;
        proxy_cache_valid 200 302 1h;
        proxy_cache_valid 404 1m;
    }
    
  • Testing Mock the CacheMiddleware in PHPUnit:

    $this->app->instance(CacheMiddleware::class, $mockMiddleware);
    

Gotchas and Tips

Pitfalls

  1. Cache Headers Overrides Custom serializers or filters may override Cache-Control headers. Ensure they respect the #[Cache] attribute:

    public function normalize($object, string $format, array $context = []): array {
        $context['cache_headers'] = ['Cache-Control' => 'public, max-age=3600'];
        return [...];
    }
    
  2. ETag/Last-Modified Conflicts If your API uses #[ApiResource] with #[Cache], ensure ETag or Last-Modified headers are not conflicting with Cache-Control. Disable one if needed:

    #[Cache(maxAge: 3600, vary: ['Accept'])]
    class Post {}
    
  3. Private Cache with Auth Avoid caching authenticated responses. Use public: false (default) and ensure Authorization headers are excluded from cache keys:

    #[Cache(maxAge: 0, public: false)]
    class UserProfile {}
    
  4. Cache Key Collisions Dynamic cache keys (e.g., based on query params) may cause collisions. Use unique suffixes:

    #[Cache(keyGenerator: class implements CacheKeyGeneratorInterface {
        public function generate(string $uri, array $context): string {
            return md5($uri . serialize($context['query']));
        }
    })]
    class SearchResult {}
    
  5. Middleware Order Place CacheMiddleware after ApiPlatform\Metadata\Middleware\CheckVersionMiddleware and before ApiPlatform\Metadata\Middleware\UnderscoreNormalizerMiddleware in Kernel.php.


Debugging

  1. Check Headers Inspect responses for Cache-Control, X-Cache, or X-Cache-Hits headers:

    curl -I http://your-api/books
    
  2. Enable Debug Mode Temporarily disable caching in config/packages/api_platform.yaml:

    api_platform:
        http_cache:
            enabled: false
    
  3. Log Cache Events Add a subscriber to log cache hits/misses:

    use ApiPlatform\HttpCache\EventListener\CacheListener;
    
    public function onKernelResponse(ResponseEvent $event): void {
        $response = $event->getResponse();
        if ($response->headers->has('X-Cache')) {
            $this->logger->info('Cache: ' . $response->headers->get('X-Cache'));
        }
    }
    

Extension Points

  1. Custom Cache Store Replace the default CacheItemPoolInterface:

    $this->app->bind(CacheItemPoolInterface::class, function () {
        return new RedisCachePool(new RedisClient());
    });
    
  2. Event Subscribers Listen to cache events (e.g., CacheEvent::INVALIDATE):

    use ApiPlatform\HttpCache\Event\CacheEvent;
    
    public static function getSubscribedEvents(): array {
        return [
            CacheEvent::INVALIDATE => 'onCacheInvalidate',
        ];
    }
    
  3. Conditional Caching Dynamically enable/disable caching based on runtime logic:

    use ApiPlatform\HttpCache\Middleware\CacheMiddleware;
    
    $middleware = new CacheMiddleware($cachePool, $cacheKeyGenerator);
    if ($this->shouldCache()) {
        $response = $middleware->handle($request, $next);
    } else {
        $response = $next($request);
    }
    
  4. Cache Warmup Pre-warm cache for critical endpoints:

    use Symfony\Component\HttpClient\HttpClient;
    
    $client = HttpClient::create();
    $client->request('GET', '/api/homepage');
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
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