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

ibexa/http-cache

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ibexa/http-cache
    

    Requires Ibexa DXP (formerly eZ Platform Enterprise) as a base.

  2. Configuration: Add the bundle to config/bundles.php:

    Ibexa\HttpCache\IbexaHttpCacheBundle::class => ['all' => true],
    
  3. Varnish Configuration: Ensure your Varnish instance is configured with the provided .vcl templates (e.g., varnish6.vcl). The bundle includes default configurations for Varnish 6/7.

  4. First Use Case: Enable caching for a controller by adding the Cacheable trait or annotation:

    use Ibexa\HttpCache\Attribute\Cacheable;
    
    #[Cacheable]
    public function show(Content $content): Response
    {
        return new Response($content->getContent());
    }
    

Key Files to Review

  • config/packages/ibexa_http_cache.yaml (default configuration)
  • src/Attribute/Cacheable.php (annotation-based caching)
  • src/Listener/ResponseTaggerListener.php (response tagging logic)

Implementation Patterns

Core Workflows

1. Annotation-Based Caching

Use the #[Cacheable] attribute on controller methods to enable HTTP caching:

#[Cacheable(
    ttl: 3600,
    varyBy: ['content_language', 'content_version'],
    tags: ['content/{content_id}']
)]
public function show(Content $content): Response
{
    return new Response($content->render());
}
  • ttl: Time-to-live in seconds (default: 300).
  • varyBy: Array of request attributes to vary cache by (e.g., ['content_language']).
  • tags: Cache tags for invalidation (e.g., ['content/123']).

2. Tag-Based Invalidation

Invalidate cache tags programmatically (e.g., after content updates):

use Ibexa\HttpCache\CacheInvalidator;

public function updateContent(Content $content): void
{
    $this->cacheInvalidator->invalidateTags(['content/' . $content->id]);
}

Inject CacheInvalidator via dependency injection.

3. Vary Headers

Dynamically add Vary headers for multi-language or multi-site setups:

use Ibexa\HttpCache\EventSubscriber\VaryHeaderSubscriber;

// Configure in services.yaml:
Ibexa\HttpCache\EventSubscriber\VaryHeaderSubscriber:
    tags:
        - { name: kernel.event_subscriber }

4. Conditional Request Handling

Use ConditionalGetListener to support If-None-Match/If-Modified-Since:

# config/packages/ibexa_http_cache.yaml
ibexa_http_cache:
    conditional_get: true

5. Varnish Integration

  • Deploy the provided varnish6.vcl or varnish7.vcl to your Varnish instance.
  • Configure backend servers in Varnish to point to your Laravel/Ibexa application.
  • Use the VarnishPurger service to purge URLs or tags:
    $this->varnishPurger->purge(['/path/to/page', '/another/path']);
    

Integration Tips

Laravel-Specific Adjustments

  1. Middleware Integration: Add the bundle’s middleware to your app/Http/Kernel.php:

    protected $middlewareGroups = [
        'web' => [
            // ...
            \Ibexa\HttpCache\Middleware\CacheMiddleware::class,
        ],
    ];
    
  2. Symfony Event Dispatcher: The bundle leverages Symfony’s event system. Extend existing listeners or create custom ones:

    use Ibexa\HttpCache\Event\CacheEvent;
    
    public function onCacheEvent(CacheEvent $event): void
    {
        if ($event->isCacheable()) {
            $event->setTtl(7200); // Override TTL
        }
    }
    
  3. Custom Response Taggers: Extend ResponseTaggerInterface to add custom tags:

    use Ibexa\HttpCache\ResponseTagger\ResponseTaggerInterface;
    
    class CustomResponseTagger implements ResponseTaggerInterface
    {
        public function getTags(Request $request, Response $response): array
        {
            return ['custom/' . $request->get('param')];
        }
    }
    

    Register the service with the ibexa.http_cache.response_tagger tag.

Ibexa DXP-Specific Features

  • Translation-Aware Caching: The bundle automatically handles language-specific cache invalidation via content_language tags.
  • Content Versioning: Use content_version in varyBy to cache different content versions separately.

Gotchas and Tips

Pitfalls

  1. Cookie Handling:

    • The bundle blocks caching if cookies are present (except those prefixed with ibexa-).
    • Fix: Ensure sensitive cookies (e.g., session_id) are excluded or prefixed correctly.
    • Debug: Check ConditionallyRemoveVaryHeaderListener if Vary: Cookie appears unexpectedly.
  2. Varnish Configuration Mismatches:

    • If Varnish returns 500 errors, verify:
      • The .vcl file is correctly deployed.
      • Backend servers in Varnish match your Laravel app’s host/port.
      • The ibexa_http_cache.varnish config in config/packages/ibexa_http_cache.yaml aligns with your Varnish version.
    • Tip: Use varnishlog to debug Varnish requests.
  3. Cache Invalidation Race Conditions:

    • Tags may not invalidate immediately due to Varnish’s background purge queue.
    • Workaround: Use purge() for critical paths (e.g., admin actions):
      $this->varnishPurger->purge(['/admin/*'], true); // Force sync purge
      
  4. TTL Too Aggressive:

    • Short TTLs (e.g., < 60s) may cause Varnish to flood your backend with requests.
    • Tip: Start with ttl: 300 and adjust based on traffic.
  5. Symfony 7+ Compatibility:

    • The bundle requires PHP 8.3+. Ensure your composer.json constraints align:
      "require": {
          "php": "^8.3",
          "symfony/*": "^7.3"
      }
      

Debugging Tips

  1. Enable Debug Headers: Add to config/packages/ibexa_http_cache.yaml:

    ibexa_http_cache:
        debug: true
    

    This adds X-Ibexa-Cache headers to responses (e.g., X-Ibexa-Cache: HIT).

  2. Log Cache Events: Configure Monolog to log Ibexa\HttpCache\Event\CacheEvent:

    monolog:
        handlers:
            cache:
                type: stream
                path: "%kernel.logs_dir%/cache.log"
                channels: ["ibexa_http_cache"]
    
  3. Check Response Tags: Use dd($response->headers->get('X-Ibexa-Cache-Tags')) to verify tags are applied correctly.

  4. Varnish Debugging:

    • Test Varnish config with varnishd -C -f /path/to/varnish.vcl.
    • Use varnishstat to monitor hit/miss ratios.

Extension Points

  1. Custom Cache Keys: Override the cache key generation in CacheKeyGeneratorInterface:

    class CustomCacheKeyGenerator implements CacheKeyGeneratorInterface
    {
        public function generate(Request $request): string
        {
            return md5($request->getPathInfo() . $request->get('custom_param'));
        }
    }
    

    Register as a service with the ibexa.http_cache.cache_key_generator tag.

  2. Dynamic TTL: Implement TtlResolverInterface to set TTLs based on runtime logic:

    class DynamicTtlResolver implements TtlResolverInterface
    {
        public function resolve(Request $request, Response $response): int
        {
            return $request->get('is_premium') ? 86400 : 3600;
        }
    }
    
  3. Edge-Side Includes (ESI): Use #[Cacheable(esi: true)] to enable ESI for partial responses:

    #[Cacheable(esi: true, ttl: 60)]
    public function partial(): Response
    {
        return new Response('<esi:include src="/partial-path" />');
    
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.
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
spatie/mailcoach-vapor
spatie/laravel-javascript-views