softspring/http-cache-store-bundle
Symfony bundle that provides an HTTP cache store for saving and retrieving cached HTTP responses, helping applications serve content faster and reduce backend load. Integrates cache storage into your Symfony stack for efficient, reusable HTTP caching.
Read this first: this is a Symfony bundle, not a Laravel package. There is no bundles.php, no DependencyInjection/Extension auto-registration, and no service container wiring in Laravel. composer require softspring/http-cache-store-bundle will autoload its classes and do nothing else. Your first hour should be spent reading src/, DependencyInjection/, and Resources/config/services.yaml to find the class that actually implements the store interface — the bundle wiring is dead weight for you; the store class is the only potentially reusable part.
Confirm two things before writing any code:
Symfony\Component\HttpKernel\HttpCache\StoreInterface? This interface ships with symfony/http-kernel, which Laravel already pulls in transitively via symfony/http-foundation. If yes, the class is technically instantiable inside Laravel.Symfony\Contracts\Cache\CacheInterface or a PSR-6 CacheItemPoolInterface, you must supply a Symfony cache adapter — Laravel's Illuminate\Contracts\Cache\Repository implements neither PSR-6 nor PSR-16.Your realistic first use case — full-page response caching for anonymous GET traffic — is better served by spatie/laravel-responsecache or a hand-rolled Cache::remember middleware. Treat that as the baseline and only reach for this package if you have a specific reason to want a Symfony StoreInterface-shaped object (for example, reusing it alongside symfony/http-kernel's HttpCache in a non-Laravel service within the same monorepo).
Minimal spike, if you proceed:
composer require softspring/http-cache-store-bundle
ls vendor/softspring/http-cache-store-bundle/src
Then instantiate the store directly in tinker with a Symfony FilesystemAdapter or ArrayAdapter and confirm write()/lookup()/invalidate() behave as documented.
Pattern 1 — Bind the store class manually in a service provider. Since the DI extension never runs, you replicate its config yourself:
// app/Providers/HttpCacheStoreServiceProvider.php
public function register(): void
{
$this->app->singleton(\Softspring\HttpCacheStore\...\Store::class, function () {
return new \Softspring\HttpCacheStore\...\Store(
new \Symfony\Component\Cache\Adapter\RedisAdapter(
\Redis::connection('cache')->client()
)
);
});
}
Pin the constructor signature against the source; the bundle's YAML defines the arguments you must mirror by hand.
Pattern 2 — Wrap Symfony HttpCache around Laravel's kernel. The only way a StoreInterface implementation earns its keep: build the HttpCache in middleware, wrapping a synthetic HttpKernelInterface that proxies to Laravel's kernel. This gives you ESI-style cache semantics and StoreInterface-driven storage, at the cost of running two HTTP caching models at once. Only viable if you disable Laravel's own cache middleware for the same routes.
Pattern 3 — Use it as a reference implementation. The most defensible day-to-day use: read how it maps StoreInterface semantics (metadata keys, digest generation, TTL expiry, purge-by-request) onto a cache pool, then implement a Laravel-native store with the same contract backed by Cache::store(). Roughly 150 lines, no AGPL entanglement, no Symfony container assumptions.
Pattern 4 — Sidecar. If you genuinely need this store's behaviour, run a Symfony process (or a Symfony micro app) that serves cached responses and let Laravel proxy to it over HTTP. Keeps the framework boundary clean; adds an operational component.
For a typical Laravel app, the correct pattern is none of the above — use Cache::remember() keyed on a normalised request signature, and invalidate via model observers with tag-aware stores (Redis, Memcached).
AGPL-3.0 is the headline risk. This is a strong copyleft licence. Running a modified version to serve users over a network obliges you to offer the corresponding source — and "modified" plausibly covers your service-provider wiring and any patched store class. Most commercial Laravel apps cannot adopt this without legal sign-off. If you only consume it unmodified as a dependency, the argument is less severe but still not free. Get this cleared before writing integration code.
No changelog. Release notes are an auto-generated compare URL. Every upgrade is a git log review. Pin an exact tag in composer.json and diff before bumping — do not use a caret constraint.
The DI extension is silently inert. Any configuration you assume is happening (cache service ID, TTL, namespace prefix, StoreInterface decoration) is not. Laravel will not error; you will simply get defaults or a container-resolution exception deep in a request. Grep the bundle's Resources/config/*.yaml and replicate every argument explicitly.
PSR-6 vs PSR-16 mismatch. The description says "PSR-6 / PSR-16-friendly adapters," which means the constructor may accept either, or may accept a Symfony-specific interface that accepts neither directly. Laravel's cache repository satisfies neither out of the box; you need symfony/cache installed and an AdapterInterface bridging to your backend. Version-align symfony/cache with whatever ships with your Laravel release or you will hit signature drift in CacheInterface::get() across Symfony 5.4 / 6 / 7.
Symfony version floor. A v5.6.x bundle line usually targets Symfony 5.4/6.x with specific PHP floors (likely 8.1+). Check composer.json in the package before assuming your PHP version and transitive Symfony constraints are compatible — a composer require that drags in a conflicting symfony/cache will break unrelated packages.
Metadata is unvalidated. The release data lists a release date of 2026-10-08, which is in the future. That is a feed-quality signal, not a real release. Do not plan around it.
Bus factor. Single-vendor namespace, 0 stars, no visible maintainer activity in the notes. Assume abandonment and plan an exit: keep the store class behind your own interface so a native implementation can be swapped in without touching callers.
Debugging tip. StoreInterface::lookup() and write() are the two methods that matter; log entries and metadata headers when wiring it up. If responses are revalidated on every request, the metadata digest or the TTL is wrong, not the backend.
How can I help you explore Laravel packages today?