Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 129 additions & 47 deletions packages/plugin-rest-cache/README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,148 @@
<div align="center">
<h1>Strapi REST Cache Plugin</h1>

<p style="margin-top: 0;">Speed-up HTTP requests with LRU cache.</p>

<p>
<a href="https://www.npmjs.org/package/@strapi-community/plugin-rest-cache">
<img src="https://img.shields.io/npm/v/@strapi-community/plugin-rest-cache/latest.svg" alt="NPM Version" />
</a>
<a href="https://www.npmjs.org/package/@strapi-community/plugin-rest-cache">
<img src="https://img.shields.io/npm/dm/@strapi-community/plugin-rest-cache" alt="Monthly download on NPM" />
</a>
<a href="https://github.com/strapi-community/plugin-rest-cache/actions/workflows/tests.yml">
<img src="https://github.com/strapi-community/plugin-rest-cache/actions/workflows/tests.yml/badge.svg" alt="Tests" />
</a>
</p>
</div>

## Table of Contents <!-- omit in toc -->

- [🚦 Current Status](#-current-status)
- [✨ Features](#-features)
- [🖐 Requirements](#-requirements)
- [🚚 Getting Started](#-getting-started)
- [Contributing](#contributing)
- [License](#license)

## 🚦 Current Status

This package is currently under development and should be consider **BETA** in terms of state. I/We are currently accepting contributions and/or dedicated contributors to help develop and maintain this package.

## ✨ Features

This plugin provide a way to cache **HTTP requests** in order to **improve performance**. It's get inspired by varnish cache which is a popular caching solution.

The cache content is stored by a **provider**, which can be either an in-memory provider, a redis connection, a file system, or any other custom provider.
You can set a **strategy** to tell what to cache and how much time responses should be cached. The cache will be invalidated when the related Content-Type is updated, so you **never have to worry about stale data**.

## 🖐 Requirements

Supported Strapi Versions:

- Strapi v5.x.x (recently tested as of September 2025)

**If you are looking for the Strapi v4.x support, please check the [legacy package](https://www.npmjs.com/package/strapi-plugin-rest-cache).**
**If you are looking for a plugin for Strapi v3.x, please check the [strapi-middleware-cache](https://github.com/patrixr/strapi-middleware-cache/).**

Node.js:

- Node `>=20.0.0`

Note that Strapi itself is the tighter constraint in practice: as of Strapi
`5.52.0`, one of its transitive dependencies requires Node `>=22.13`, so a
Strapi 5 application cannot be installed on Node 20 even though this plugin
supports it.

## 🚚 Getting Started

[Read the Docs to Learn More.](https://strapi-community.github.io/plugin-rest-cache/)
A caching layer for the Strapi REST API. It injects a middleware that stores `GET`
responses, keyed by route and query, and invalidates them when the underlying
content changes — so you serve cached responses without serving stale ones.

Cached content lives in a **provider** (in-memory, Redis, or your own). What gets
cached, and for how long, is described by a **strategy** in your plugin config.

![REST Cache admin panel](https://raw.githubusercontent.com/strapi-community/plugin-rest-cache/main/docs/public/screenshots/settings-overview.png)

## Features

- **Pluggable providers.** In-memory by default; Redis via
`@strapi-community/provider-rest-cache-redis`. Custom providers implement the
`CacheProvider` abstract class.
- **Per-content-type and per-route caching.** Cache a list of content types with
their default routes, or declare custom routes with their own `maxAge`,
`paramNames` and key strategy.
- **Configurable cache keys.** Key on query params (`keys.useQueryParams`),
specific request headers (`keys.useHeaders`), and — *since 5.1.0* — on the
authenticated caller (`keys.useAuth`), so two callers authorised for the same
route do not share one entry.
- **Automatic invalidation through the document service.** *Since 5.1.0*,
invalidation hooks `strapi.documents()` rather than HTTP routes, so it catches
GraphQL mutations, admin panel edits, scheduled Content Releases and any custom
`strapi.documents()` call — not only REST writes. Related content types can be
purged alongside (`clearRelatedCache`).
- **Request coalescing.** *Since 5.1.0*, N concurrent misses on the same key make
one call to the origin and the rest wait on it. Matters on cold start, right
after a purge, and at TTL expiry.
- **ETag and `304 Not Modified`** support (`enableEtag`).
- **`X-Cache` response headers** — `HIT`, `MISS`, `HITPASS` (`enableXCacheHeaders`).
- **Hitpass.** A per-request predicate that bypasses the cache entirely. The
default bypasses any request carrying an `Authorization` header or a cookie.
- **Admin dashboard.** *Since 5.1.0*, Settings → REST Cache shows the resolved
strategy, live entry counts per content type, and purge controls.
- **Homepage widget.** *Since 5.1.0*, a summary of what the cache currently holds.
- **Content-manager controls.** *Since 5.1.0*, a cache panel on the edit view plus
purge actions on the edit and list views.
- **Programmatic purging.** Admin routes and internal services, plus an opt-in
content API purge endpoint (`enableContentApiPurge`).

## Requirements

- Strapi `>= 5.0.0`
- Node `>= 20`

Looking for Strapi v4? Use the [legacy package](https://www.npmjs.com/package/strapi-plugin-rest-cache).
Looking for Strapi v3? Use [strapi-middleware-cache](https://github.com/patrixr/strapi-middleware-cache/).

## Quick start

Install the plugin.

npm:

```bash
npm install @strapi-community/plugin-rest-cache
```

yarn:

```bash
yarn add @strapi-community/plugin-rest-cache
```

pnpm:

```bash
pnpm add @strapi-community/plugin-rest-cache
```

Then list the content types you want cached in `./config/plugins.js`:

```js
module.exports = {
'rest-cache': {
config: {
provider: {
name: 'memory',
options: {
maxSize: 32767,
},
},
strategy: {
contentTypes: [
'api::category.category',
'api::article.article',
'api::homepage.homepage',
],
},
},
},
};
```

That caches the default `find` and `findOne` routes of those content types for one
hour (`maxAge`, in milliseconds) and purges them when their content changes.

For Redis, install `@strapi-community/plugin-redis` and
`@strapi-community/provider-rest-cache-redis` alongside the plugin and set
`provider.name` to `redis` — see the
[installation guide](https://strapi-community.github.io/plugin-rest-cache/guide/getting-started).

## Documentation

Full documentation lives at
**[strapi-community.github.io/plugin-rest-cache](https://strapi-community.github.io/plugin-rest-cache/)**.

- [Installation](https://strapi-community.github.io/plugin-rest-cache/guide/getting-started)
- [Provider configuration](https://strapi-community.github.io/plugin-rest-cache/guide/providers/) —
[memory](https://strapi-community.github.io/plugin-rest-cache/guide/providers/memory),
[redis](https://strapi-community.github.io/plugin-rest-cache/guide/providers/redis),
[custom](https://strapi-community.github.io/plugin-rest-cache/guide/providers/custom)
- [Strategy configuration](https://strapi-community.github.io/plugin-rest-cache/guide/reference/config) —
[content types](https://strapi-community.github.io/plugin-rest-cache/guide/caching/content-types),
[custom routes](https://strapi-community.github.io/plugin-rest-cache/guide/caching/custom-routes),
[cache keys](https://strapi-community.github.io/plugin-rest-cache/guide/caching/keys),
[debug mode](https://strapi-community.github.io/plugin-rest-cache/guide/troubleshooting)
- [Services and admin routes](https://strapi-community.github.io/plugin-rest-cache/guide/reference/services)

## Contributing

I/We are actively looking for contributors, maintainers, and others to help shape this package. As this plugins sole purpose within the Strapi community is to be used by other developers and plugin maintainers to get fast responses time.

If interested please feel free to open an issue or pull request.
Contributors and maintainers are wanted. See [CONTRIBUTING.md](https://github.com/strapi-community/plugin-rest-cache/blob/main/CONTRIBUTING.md)
for the repo layout, how to run the playgrounds, and how to run the test suites.
Bugs and feature requests go in
[issues](https://github.com/strapi-community/plugin-rest-cache/issues).

## License

See the [LICENSE](./LICENSE.md) file for licensing information.
See the [LICENSE](https://github.com/strapi-community/plugin-rest-cache/blob/main/LICENSE) file for licensing information.
111 changes: 111 additions & 0 deletions packages/provider-rest-cache-memory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<div align="center">
<h1>REST Cache — Memory Provider</h1>

<p style="margin-top: 0;">In-process cache storage for <code>@strapi-community/plugin-rest-cache</code>.</p>

<p>
<a href="https://www.npmjs.org/package/@strapi-community/provider-rest-cache-memory">
<img src="https://img.shields.io/npm/v/@strapi-community/provider-rest-cache-memory/latest.svg" alt="NPM Version" />
</a>
<a href="https://www.npmjs.org/package/@strapi-community/provider-rest-cache-memory">
<img src="https://img.shields.io/npm/dm/@strapi-community/provider-rest-cache-memory" alt="Monthly downloads on NPM" />
</a>
</p>
</div>

Stores cache entries in the Strapi process, in an LRU bounded by entry count.
This is the default provider and ships with the plugin, so you rarely need to
install it yourself.

## When to use it

Use it when you run **one** Strapi instance.

Each process holds its own cache, so with two or more instances behind a load
balancer they cache independently and a purge on one does not reach the others
— one instance serves fresh content while another serves stale. Entries are
also lost on restart. If either matters, use
[`@strapi-community/provider-rest-cache-redis`](https://www.npmjs.com/package/@strapi-community/provider-rest-cache-redis).

## Install

Already a dependency of the plugin. Install it explicitly only if you want to
pin its version:

```bash
npm install @strapi-community/provider-rest-cache-memory
```

```bash
yarn add @strapi-community/provider-rest-cache-memory
```

```bash
pnpm add @strapi-community/provider-rest-cache-memory
```

## Configure

```js
// ./config/plugins.js
module.exports = {
"rest-cache": {
config: {
provider: {
name: "memory",
options: {
maxSize: 32767,
// Milliseconds. One hour.
ttl: 3600000,
},
},
strategy: {
contentTypes: ["api::article.article"],
},
},
},
};
```

```ts
// ./config/plugins.ts
export default {
"rest-cache": {
config: {
provider: {
name: "memory",
options: {
maxSize: 32767,
// Milliseconds. One hour.
ttl: 3600000,
},
},
strategy: {
contentTypes: ["api::article.article"],
},
},
},
};
```

### Options

| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `maxSize` | `number` | `32767` | Maximum number of entries before the least recently used one is evicted. Must be greater than 0. |
| `ttl` | `number` (ms) | — | Store-level default lifetime. In practice the plugin passes an explicit lifetime on every write from `strategy.maxAge`, so this is only a backstop. |

`max` is accepted as a legacy alias for `maxSize`.

> **Durations are milliseconds.** `3600000` is one hour; `3600` is 3.6 seconds.
> Set the lifetime you actually care about with `strategy.maxAge`.

## Documentation

- [Memory provider](https://strapi-community.github.io/plugin-rest-cache/guide/providers/memory.html)
- [Choosing a provider](https://strapi-community.github.io/plugin-rest-cache/guide/providers/)
- [Configuration reference](https://strapi-community.github.io/plugin-rest-cache/guide/reference/config.html)

## License

See the [LICENSE](https://github.com/strapi-community/plugin-rest-cache/blob/main/LICENSE) file.
Loading
Loading