API Response Caching Middleware for Express/Node

raw JSON →
1.6.3 verified Thu Apr 23 auth: no javascript

apicache is an ultra-simplified middleware for Express.js and Node.js designed to cache API responses. It supports both an in-memory store and Redis as a backend, allowing developers to define cache durations using plain-english strings (e.g., '5 minutes'). The current stable version is 1.6.3, with version 1.0.0 marking a production-ready release after extensive use. The project appears to have a moderate release cadence, focusing on stability and adding features incrementally, such as `res.write` support and official `compression` integration. Its key differentiator is its ease of use and 'automagic' caching injection into routes, making it a straightforward choice for basic API caching needs compared to more complex caching solutions.

error TypeError: apicache.middleware is not a function
cause Incorrect import pattern, attempting to destructure `middleware` from `apicache` directly, or not importing `apicache` at all.
fix
Ensure you are importing the default apicache object: import apicache from 'apicache'; and then accessing middleware as a property: let cache = apicache.middleware;
error Error: Redis connection to localhost:6379 failed - connect ECONNREFUSED
cause The Redis server is not running or is not accessible at the specified host and port.
fix
Start your Redis server, verify its configuration (host/port), and ensure your application has network access to it. If using a custom URL, ensure redis.createClient({ url: '...' }) is correct.
error ReferenceError: require is not defined in ES module scope
cause Attempting to use CommonJS `require()` syntax in an ES Module (`.mjs` file or `type: "module"` in `package.json`) environment.
fix
Replace const apicache = require('apicache'); with import apicache from 'apicache';
error Cache is not clearing/invalidating as expected.
cause Incorrect `apicache.clear()` target, or misunderstanding of cache grouping.
fix
Verify the target string passed to apicache.clear(target) matches an exact URL path or a req.apicacheGroup name. Use apicache.getIndex() to inspect current cached entries and groups to ensure correct targeting.
gotcha When using `apicache` with the `compression` middleware, ensure `compression` is applied *before* `apicache` in the middleware chain for `apicache` to cache the compressed response. Older versions might have had issues with header mutation, but v0.8.0 and later addressed this.
fix Ensure `app.use(compression());` comes before `app.use(apicache.middleware('duration'));` or before any route-specific cache middleware.
breaking The injection of `apicache-store` and `apicache-version` headers moved from before cache-injection to response-building from cache. This means middleware interceptors will only detect these headers when a response is actually served from the cache, not when the request is initially processed.
fix Adjust any custom middleware that relies on `apicache` headers to check for their presence during the response phase, specifically when a cache hit occurs.
gotcha Debugging output for apicache, while configurable via `apicache.options({ debug: true })`, is now primarily and preferentially controlled via the `DEBUG` environment variable, specifically `DEBUG=apicache`.
fix For detailed logging, set the environment variable `export DEBUG=apicache` before running your Node.js application instead of relying solely on `options({ debug: true })`.
breaking apicache requires Node.js version 8 or higher. Using it with older Node.js versions will lead to compatibility issues or failures.
fix Upgrade your Node.js environment to version 8 or newer.
gotcha When using `apicache.options()` to configure global settings (like `redisClient` or custom `headers`), ensure you apply it before initializing your `apicache.middleware`. Calling `options` modifies the global `apicache` object.
fix Set global options before creating or using the `middleware` instance: `let cache = apicache.options({ /* ... */ }).middleware;`
npm install apicache
yarn add apicache
pnpm add apicache

This example sets up an Express server with `apicache` configured for either in-memory or Redis caching. It demonstrates how to apply caching middleware to a route, retrieve cache performance metrics, view the cache index, and manually clear cached entries by target or group.

import express from 'express';
import apicache from 'apicache';
import redis from 'redis'; // Optional: for Redis integration

const app = express();

// --- Configuration for in-memory cache ---
let cache = apicache.middleware;

// --- Configuration for Redis cache (uncomment to use) ---
// const redisClient = redis.createClient({ url: process.env.REDIS_URL ?? 'redis://localhost:6379' });
// redisClient.on('error', (err) => console.error('Redis Client Error', err));
// redisClient.connect(); // Connect the client
// let cache = apicache.options({ redisClient }).middleware;

// Basic cached route (in-memory or Redis based on config above)
app.get('/api/data', cache('1 minute'), (req, res) => {
  console.log('Fetching fresh data for /api/data');
  res.json({ timestamp: new Date(), value: Math.random() });
});

// Route to check cache performance and index
app.get('/api/cache/performance', (req, res) => {
  res.json(apicache.getPerformance());
});

app.get('/api/cache/index', (req, res) => {
  res.json(apicache.getIndex());
});

// Route to manually clear cache (e.g., all entries, or a specific target/group)
app.get('/api/cache/clear/:target?', (req, res) => {
  const target = req.params.target || 'all'; // 'all' clears everything if no target is specified
  console.log(`Clearing cache for target: ${target}`);
  res.json(apicache.clear(target));
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
  console.log('Try visiting http://localhost:3000/api/data multiple times quickly.');
  console.log('Then try http://localhost:3000/api/cache/clear');
});