Script Valley
Express.js: APIs and Middleware
Advanced Middleware PatternsLesson 5.4

Response caching middleware — how to cache API responses

in-memory cache, Cache-Control headers, cache key generation, TTL expiry, cache invalidation, stale data tradeoff, when to cache, ETag concept

API Response Caching Middleware

Caching stores the result of expensive operations so repeated requests get the cached response instead of re-running the work.

Simple in-memory cache middleware

const cache = new Map();

function cacheMiddleware(ttlSeconds = 60) {
  return (req, res, next) => {
    if (req.method !== 'GET') return next(); // only cache GET

    const key = req.originalUrl;
    const cached = cache.get(key);

    if (cached && Date.now() < cached.expiresAt) {
      res.set('X-Cache', 'HIT');
      return res.json(cached.data);
    }

    // Intercept res.json to capture the response
    const originalJson = res.json.bind(res);
    res.json = (data) => {
      cache.set(key, { data, expiresAt: Date.now() + ttlSeconds * 1000 });
      res.set('X-Cache', 'MISS');
      return originalJson(data);
    };

    next();
  };
}

// Cache public endpoints for 5 minutes
app.get('/products', cacheMiddleware(300), getProducts);
app.get('/categories', cacheMiddleware(600), getCategories);

The X-Cache: HIT/MISS header lets you verify caching in browser DevTools. In-memory caching doesn't survive restarts — use Redis for production. Never cache authenticated endpoints or responses containing user-specific data.

Up next

How to structure Express middleware for large-scale applications

Sign in to track progress