PHPackages                             studocu/cacheable-entities - 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. [Caching](/categories/caching)
4. /
5. studocu/cacheable-entities

ActiveLibrary[Caching](/categories/caching)

studocu/cacheable-entities
==========================

Cacheable entities are an abstraction layer to extract away cache-related responsibilities.

v1.0.0(2y ago)11338.6k↓19.8%[3 PRs](https://github.com/StuDocu/cacheable-entities/pulls)MITPHPPHP ^8.1CI passing

Since Feb 9Pushed 1y ago6 watchersCompare

[ Source](https://github.com/StuDocu/cacheable-entities)[ Packagist](https://packagist.org/packages/studocu/cacheable-entities)[ Docs](https://github.com/StuDocu/cacheable-entities)[ RSS](/packages/studocu-cacheable-entities/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (5)Used By (0)

### Cacheable entities

[](#cacheable-entities)

[![Tests](https://github.com/StuDocu/cacheable-entities/actions/workflows/run-tests.yml/badge.svg)](https://github.com/StuDocu/cacheable-entities/actions/workflows/run-tests.yml)[![Codecov](https://camo.githubusercontent.com/804dd37a50a39f332f5abb25b62c914f5d4dca7586605dbb45b8ccbd5bb35221/68747470733a2f2f636f6465636f762e696f2f67682f537475446f63752f636163686561626c652d656e7469746965732f67726170682f62616467652e7376673f746f6b656e3d42424d4b4a4151305a31)](https://codecov.io/gh/StuDocu/cacheable-entities)

Cacheable entities is an opinionated infrastructure acts as an abstraction layer to extract away cache-related responsibilities.

```
class RecommendedBooksQuery implements Cacheable, SerializableCacheable
{
    public function getCacheTTL(): int
    {
        return 3600 * 24;
    }

    public function getCacheKey(): string
    {
        return "books:popular.v1";
    }

    public function get(): Collection
    {
        return Book::query()
            ->wherePopular()
            ->orderByDesc('document_popularity_scores.score')
            ->take(config('popular.books.limit'))
            ->get();
    }

    public function serialize(mixed $value): array
    {
        return $value->pluck('id')->all();
    }

    public function unserialize(mixed $value): Collection
    {
        return Book::query()->findMany($value);
    }
}

$query = new RecommendedBooksQuery();

// Get a non-blocking cache result in the web endpoint.
resolve(AsyncCache::class)->get($query);

// Get a blocking cache result in the API endpoint.
resolve(SyncCache::class)->get($query);

// Get real time value
$query->get();
```

Features
--------

[](#features)

- Encapsulated key and TLL management.
- Blocking/Non-blocking caching strategies.
- Easily serialize/unserialize cache values.
- Customize Cache Miss resolution.
- Direct access to real-time values (not through cache).

Table of contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Backstory](#backstory)
- [Usage](#usage)
    - [Defining a cacheable entity](#defining-a-cacheable-entity)
    - [Accessing a cacheable entity](#accessing-a-cacheable-entity)
        - [Caching Strategies](#caching-strategies)
        - [Access](#access)
            - [Via cache](#via-cache)
            - [Without cache](#without-cache)
    - [Serialization/Unserialization](#serializationunserialization)
        - [Corrupt serialized cache value](#corrupt-serialized-cache-value)
        - [Caveat when unserializing](#caveat-when-unserializing)
    - [Purging the cache](#purging-the-cache)
    - [Async cache default value](#async-cache-default-value)
    - [Self Cacheable Entities](#self-cacheable-entities)
    - [Generic Annotation](#generic-annotation)
        - [Cacheable Generic](#cacheable-generic)
        - [SerializableCacheable](#serializablecacheable)
        - [SupportsDefaultValue](#supportsdefaultvalue)
- [Examples](#examples)
- [Changelog](#changelog)
- [License](#license)

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require studocu/cacheable-entities
```

Backstory
---------

[](#backstory)

At [Studocu](https://www.studocu.com) we deal with a large stream of data and requests. At some point of our growth we found ourselves drowning in cache keys and caching all over the place. Thus, to bring a uniform approach to caching across our codebase, we cooked up an internally standardized (or as we like to call it, opinionated) infrastructure known as "Cacheable Entities". This infrastructure acts as an abstraction layer to extract away cache-related responsibilities. We isolated this infrastructure into a standalone Laravel package and made it open-source.

Read more about the backstory at &lt;[Cacheable Entities: A Laravel package with a story](https://medium.com/studocu-techblog/cacheable-entities-a-laravel-package-with-a-story-239a8bfc8043)&gt;.

Usage
-----

[](#usage)

### Defining a cacheable entity

[](#defining-a-cacheable-entity)

To make a class cacheable entity, it has to implement the `StuDocu\CacheableEntities\Contracts\Cacheable` contract.

The interface implementation requires defining the following methods:

- `getCacheTTL`: Returns the TTL of the cache in seconds.
- `getCacheKey`: Returns the cache key.
- `get`: Computes the Entity value.

### Accessing a cacheable entity

[](#accessing-a-cacheable-entity)

#### Caching Strategies

[](#caching-strategies)

In some cases, you might need to have the same entity cached/accessed differently; Either blocking or non-blocking.

- Blocking Cache (Synchronous): If we don't have the value, we compute it, cache it, and serve up the result right away.
- Non-blocking Cache (Asynchronous): if we don't have the value, we dispatch a job to compute it, and return an empty state (like null, empty collection, or an empty array).

#### Access

[](#access)

##### Via cache

[](#via-cache)

To use any of the two caching strategies described above, we have access to two available utility classes: `SyncCache` and `AsyncCache`.

- `StuDocu\CacheableEntities\SyncCache@get`: Accepts a cacheable entity and will wait and cache the result if not pre-cached yet.
- `StuDocu\CacheableEntities\AsyncCache@get`: Accepts a cacheable entity and will dispatch a job to compute the entity value if not pre-cached already then return an empty state. Otherwise, it will return the cached value.

> ⚠️ **Important**: If you have multi servers infrastructure, and you plan to use a cacheable entity asynchronously, make sure to create and deploy the entity separately first without using `asyncCache`. Otherwise, you might have class (Job) unserialization errors when deploying. Some regions might be deployed before others.

**Example**

```
