PHPackages                             codewiser/http-cache-control - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. codewiser/http-cache-control

ActiveLibrary[HTTP &amp; Networking](/categories/http)

codewiser/http-cache-control
============================

Http Cache Control layer for Laravel

v2.1.9(1y ago)0850↓50%11MITPHPPHP ^8.0

Since Feb 10Pushed 11mo ago2 watchersCompare

[ Source](https://github.com/C0deWiser/http-cache-control)[ Packagist](https://packagist.org/packages/codewiser/http-cache-control)[ RSS](/packages/codewiser-http-cache-control/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (21)Used By (1)

HTTP Cache-Control for Laravel
==============================

[](#http-cache-control-for-laravel)

This package provides solution to work with HTTP Cache-Control headers. Resources are cached and then invalidates on Eloquent events. Server may respond without making database requests, just using cache values.

Prepare models
--------------

[](#prepare-models)

`CacheControl` uses cache to keep headers values. Then model is changed the associated cache must be invalidated.

The models must implement `\Codewiser\HttpCacheControl\Contracts\Cacheable`.

Here is example of implementation. Classes share cache tag, so changing any Model invalidates shared cache.

```
use Codewiser\HttpCacheControl\Contracts\Cacheable;
use Codewiser\HttpCacheControl\Observers\InvalidatesCache;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Psr\SimpleCache\CacheInterface;

#[ObservedBy(InvalidatesCache::class)]
class User extends Model implements Cacheable
{
    public function cache(): CacheInterface
    {
        return Cache::tags(['user', 'order']);
    }
}

#[ObservedBy(InvalidatesCache::class)]
class Order extends Model implements Cacheable
{
    public function cache(): CacheInterface
    {
        return Cache::tags(['order', 'user']);
    }
}
```

Usage
-----

[](#usage)

`CacheControl` class analyzes request headers and creates response with proper headers.

First argument must be a `\Psr\SimpleCache\CacheInterface`, or `\Codewiser\HttpCacheControl\Contracts\Cacheable`, or classname of a Model, that implements that interface.

The second argument is a callback, that should return response content. This callback would be called only if necessary.

### `Cache-Control` header

[](#cache-control-header)

You may set any `Cache-Control` directives you like:

```
use Codewiser\HttpCacheControl\CacheControl;
use Codewiser\HttpCacheControl\CacheControlHeader;

public function index(Request $request)
{
    return CacheControl::make(Order::class,
        fn(Request $request) => OrderResource::collection(Order::all())
    )
        ->cacheControl(fn(Request $request) => new CacheControlHeader(
            public: true,
            max_age: 1800,
            must_revalidate: true,
        ));
}
```

> If no `public` or `private` directives was not set, it would be `private` by default.

> Nothing would be cached on server in this case.

### `Expires` header

[](#expires-header)

Or you may set only `Expires` header:

```
use Codewiser\HttpCacheControl\CacheControl;
use Codewiser\HttpCacheControl\CacheControlHeader;

public function index(Request $request)
{
    return CacheControl::make(Order::class,
        fn(Request $request) => OrderResource::collection(Order::all())
    )
        ->expires(now()->addHour());
}
```

> Nothing would be cached on server in this case.

### Caching entire response

[](#caching-entire-response)

You may want to cache the entire response:

```
use Codewiser\HttpCacheControl\CacheControl;
use Codewiser\HttpCacheControl\CacheControlHeader;

public function index(Request $request)
{
    return CacheControl::make(Order::class,
        fn(Request $request) => OrderResource::collection(Order::all())
    )
        ->remember()
        ->cacheControl(new CacheControlHeader(
            public: true,
            max_age: now()->addHour(),
            must_revalidate: true,
        ));
}
```

> Use with care. Note, that cache may become huge.

### Private Cache

[](#private-cache)

If controller response must not be shared across users, you should set `Cache-Control: private` directive.

```
use Codewiser\HttpCacheControl\CacheControl;
use Codewiser\HttpCacheControl\CacheControlHeader;

public function index(Request $request)
{
    return CacheControl::make(Order::class,
        fn(Request $request) => OrderResource::collection(
            Order::query()->whereBelongsTo($request->user())->get()
        )
    )
        ->cacheControl(new CacheControlHeader(
            private: true,
            max_age: new DateInterval('PT1H'),
            must_revalidate: true,
        ));
}
```

### `Vary` header

[](#vary-header)

`Vary` headers describes a list of request headers, that matters for caching.

For example, your application supports different languages, so cache depends on `Accept-Language` request header:

```
use Codewiser\HttpCacheControl\CacheControl;
use Codewiser\HttpCacheControl\CacheControlHeader;

public function index(Request $request)
{
    return CacheControl::make(Order::class,
        fn(Request $request) => OrderResource::collection(Order::all())
    )
        ->vary('Accept-Language')
        ->cacheControl(new CacheControlHeader(
            public: true,
            max_age: 1800,
            must_revalidate: true,
        ));
}
```

> Note, that web-server may append more Vary headers values. It is `Accept-Encoding` as usual.

### Conditional headers

[](#conditional-headers)

Controller may respond with `ETag` and/or `Last-Modified` header, so the next request may bring `If-None-Match` or `If-Modified-Since` headers, that makes it conditional.

```
use Codewiser\HttpCacheControl\CacheControl;
use Codewiser\HttpCacheControl\CacheControlHeader;

public function index(Request $request)
{
    return CacheControl::make(Order::class,
        fn(Request $request) => OrderResource::collection(Order::all())
    )
        ->cacheControl(['public' => true])
        // Implicit
        ->etag()
        // Or explicit
        ->etag(fn() => custom_etag_calculation(Order::all()));
}
```

In this example local cache stores only `ETag` value. That would be enough to check future requests with `If-None-Match`.

This way is the most cache careful.

```
use Codewiser\HttpCacheControl\CacheControl;
use Codewiser\HttpCacheControl\CacheControlHeader;

public function index(Request $request)
{
    return CacheControl::make(Order::class,
        fn(Request $request) => OrderResource::collection(Order::all())
    )
        ->cacheControl(['public' => true])
        // Return timestamp or DateTimeInterface
        ->lastModified(fn() => Order::all()->max('updated_at'));
}
```

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance47

Moderate activity, may be stable

Popularity17

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~38 days

Recently: every ~70 days

Total

20

Last Release

452d ago

Major Versions

v1.0.4 → v2.0.02023-11-03

PHP version history (2 changes)v1.0.0PHP ^7.4|^8.0

v2.0.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/ce23eaf7ae48d79d2b07efc83ff7cecb2664f428bd531b167b90169423f1453d?d=identicon)[Cellard](/maintainers/Cellard)

---

Top Contributors

[![Cellard](https://avatars.githubusercontent.com/u/1220316?v=4)](https://github.com/Cellard "Cellard (27 commits)")

---

Tags

cache-controllaravelhttplaravelcache-control

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/codewiser-http-cache-control/health.svg)

```
[![Health](https://phpackages.com/badges/codewiser-http-cache-control/health.svg)](https://phpackages.com/packages/codewiser-http-cache-control)
```

###  Alternatives

[sven/super-basic-auth

A lightweight package to add basic authentication to your Laravel app.

232.6k](/packages/sven-super-basic-auth)[behamin/service-proxy

for proxy or sending requests to other services with useful utilities

102.2k](/packages/behamin-service-proxy)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
