ETag / Cache-Control headers on Strapi REST API

Hello,

I am looking for ways to add some simple HTTP caching behaviour to a Strapi REST API. For instance, how could I:

  • add a Cache-Control header in responses (e.g. public)
  • generate and set ETag headers in responses
  • respond 304 Not Modified when an If-None-Match header is provided

The goals would be to optimise the end user experience and reduce the load on the server.

Any suggestion will be appreciated :slightly_smiling_face:

A new Strapi user

This topic has been created from a Discord post (1256552150226698281) to give it more visibility.
It will be on Read-Only mode here.
Join the conversation on Discord

Hi,

So, I talking from top of my head, so maybe something is not accurate, but for: the Cache-Con

Yep the middleware is way to go

Hello,

I dug a little deeper into this subject and managed to achieve my goal in just a few lines of code, by reusing a combination of Koa middlewares: koa-cache-control, koa-conditional-get and koa-etag:

It can certainly be improved, but here is my code that may help others:

import { ParameterizedContext } from "koa";
import cacheControl from "koa-cache-control";
import koaConditionalGet from "koa-conditional-get";
import koaEtag from "koa-etag";

const cacheControlMiddleware = cacheControl({
  // TODO Write here the default cache control settings you want for your API
});

const conditionalMiddleware = koaConditionalGet();

const etagMiddleware = koaEtag();

export default () =>
  async (context: ParameterizedContext, next: () => Promise<any>) => {
    await next();

    // Exclude non cacheable methods
    if (!["HEAD", "GET"].includes(context.request.method)) {
      return;
    }

    // Exclude non successful responses
    if (context.status < 200 || context.status >= 300) {
      return;
    }

    await etagMiddleware(context, () => Promise.resolve());
    await conditionalMiddleware(context, () => Promise.resolve());
    await cacheControlMiddleware(context, () => Promise.resolve());
  };