Skip to content

Configuration reference

Every option the plugin accepts, with its type, default, and what it is for. Configuration lives in ./config/plugins.js (or .ts) under the rest-cache key.

Durations are milliseconds

maxAge and the providers' ttl are milliseconds, everywhere, without exception. 3600000 is one hour.

This is worth stating loudly because getting it wrong is silent: the plugin once multiplied an already-millisecond value by 1000 before handing it to the store, so a configured hour lived 41.7 days and nothing ever expired. (#126)

Shape

js
// ./config/plugins.js
module.exports = {
  "rest-cache": {
    config: {
      provider: {
        /* ... */
      },
      strategy: {
        /* ... */
      },
    },
  },
};
ts
// ./config/plugins.ts
export default {
  "rest-cache": {
    config: {
      provider: {
        /* ... */
      },
      strategy: {
        /* ... */
      },
    },
  },
};

provider

Where cache entries are stored. See Providers.

OptionTypeDefaultDescription
namestring"memory"Which provider to load. Resolves the package @strapi-community/provider-rest-cache-<name>.
getTimeoutnumber (ms)500How long a cache read may take before the plugin gives up and treats it as a miss. A slow store degrades to no cache rather than to a slow site.
optionsobjectprovider-specificPassed straight through to the provider.

strategy

What to cache, for how long, and how to key it.

Top level

OptionTypeDefaultDescription
contentTypesarray[]The content types to cache. See below.
maxAgenumber (ms)3600000Default lifetime for an entry. Overridable per content type and per route.
keysobjectsee keysDefault cache-key composition. Overridable per content type and per route.
hitpassfunction | booleanbypasses requests with an authorization or cookie headerDecides per request whether to skip the cache entirely. See hitpass.
keysPrefixstring""Prefixes every stored key, so the cache can share a keyspace with other consumers. If your Redis uses a keyPrefix, match it here.
enableEtagbooleanfalseEmit an ETag and answer 304 Not Modified when it matches.
enableXCacheHeadersbooleanfalseEmit X-Cache: HIT | MISS | HITPASS. Useful in development and for debugging a CDN in front.
enableDocumentServiceMiddlewarebooleantrueInvalidate from the document service rather than from HTTP routes. See Invalidation. since 5.1.0
enableContentApiPurgebooleanfalseExpose POST /api/rest-cache/purge. Off by default; see Purging. since 5.1.0
enableAdminCTBMiddlewarebooleantrueInject purge middleware into the content-manager's admin routes. Superseded by enableDocumentServiceMiddleware and ignored while that is on.
clearRelatedCachebooleantrueWhen a content type is purged, also purge content types related to it through relations and components, transitively.
resetOnStartupbooleanfalseEmpty the cache when Strapi boots.
debugbooleanfalseEnable the plugin's debug logging namespace. See Debugging.

contentTypes

Each entry is either a uid string, or an object for finer control.

js
contentTypes: [
  // Shorthand: cache this content type's default routes with the defaults above.
  "api::article.article",

  // Full form.
  {
    contentType: "api::category.category",
    maxAge: 60000,
    hitpass: false,
    injectDefaultRoutes: true,
    keys: { useQueryParams: true, useHeaders: [], useAuth: true },
    routes: [
      /* ... */
    ],
  },
];
OptionTypeDefaultDescription
contentTypestringThe uid, e.g. api::article.article. Required.
maxAgenumber (ms)inherits strategy.maxAgeEntry lifetime for this content type.
hitpassfunction | booleaninherits strategy.hitpassPer-request bypass for this content type.
keysobjectinherits strategy.keysKey composition for this content type.
injectDefaultRoutesbooleantrueRegister the content type's own REST routes automatically. Set to false for a content type with no default routes, or to list routes by hand.
routesarray[]Extra routes to cache. See routes.

Content types owned by a plugin

Plugins do not have default API routes, so injectDefaultRoutes does nothing for them. List their routes explicitly.

routes

Each entry is either a path string, or an object.

OptionTypeDefaultDescription
pathstringThe path as Strapi registered it, including the API prefix, e.g. /api/articles/slug/:slug. Required.
methodstring"GET"HTTP method. Only GET responses are stored; other methods are used to derive purges when running without the document service middleware.
maxAgenumber (ms)inherits the content typeEntry lifetime for this route.
hitpassfunction | booleaninherits the content typePer-request bypass for this route.
keysobjectinherits the content typeKey composition for this route.
paramNamesstring[]derived from pathRoute parameter names. Derived automatically; only set this if you know you need to.

keys

How the cache key is built. See Cache keys for the full composition.

OptionTypeDefaultDescription
useQueryParamsboolean | string[]truetrue includes every query parameter. An array includes only those named. false ignores the query string entirely — every query then shares one entry.
useHeadersstring[][]Request headers to include in the key. Comparable to a Vary.
useAuthbooleanfalseKey entries per authenticated caller. since 5.1.0

Caching authenticated responses

useAuth exists for the case where you have deliberately turned hitpass off. Without it, two callers authorised for the same route share one entry, so whoever misses first decides what everybody else sees.

The server logs a warning at boot when a content type sets hitpass: false without keys.useAuth.

hitpass

A function taking the Koa context and returning a boolean (or a promise of one). true means bypass the cache for this request: nothing is read, and the response is not stored.

The shipped default bypasses any request that carries an authorization or cookie header, which is the conservative choice — it means authenticated traffic is never accelerated, but also never shared between callers.

js
// ./config/plugins.js
module.exports = {
  "rest-cache": {
    config: {
      strategy: {
        // Cache authenticated traffic, keyed per caller.
        hitpass: false,
        keys: { useAuth: true },
        contentTypes: ["api::article.article"],
      },
    },
  },
};
ts
// ./config/plugins.ts
import type { Context } from "koa";

export default {
  "rest-cache": {
    config: {
      strategy: {
        // Or decide per request.
        hitpass: (ctx: Context) => ctx.request.headers["x-preview"] === "1",
        contentTypes: ["api::article.article"],
      },
    },
  },
};

What is never cached

Independently of configuration, a response is not stored when:

  • the handler took over the socket (ctx.respond = false);
  • the body is empty, or the status is not 2xx;
  • the body is a stream — it can only be consumed once, so a stored copy could not be replayed;
  • the response sets a Set-Cookie — replaying it would hand one caller's session to everybody sharing the key;
  • the response says Cache-Control: no-store or private.
since 5.1.0 — see

#133.