Bird
Raised Fist0
Expressframework~10 mins

Cache middleware pattern in Express - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Cache middleware pattern
Incoming Request
↓
Check Cache for Data
↓
Return Cached Data
↓
Send Response
↓
Store Data in Cache
↓
Send Response
The middleware checks if data is in cache. If yes, it returns cached data. If no, it fetches fresh data, stores it in cache, then sends response.
Execution Sample
Express
const cache = {};

function cacheMiddleware(req, res, next) {
  const key = req.url;
  if (cache[key]) {
    return res.send(cache[key]);
  }
  res.sendResponse = res.send.bind(res);
  res.send = (body) => {
    cache[key] = body;
    res.sendResponse(body);
  };
  next();
}
This middleware checks if the response for the request URL is cached. If yes, it sends cached data. Otherwise, it overrides res.send to cache the response before sending.
Execution Table
StepActionCache StateResponse SentNext Called
1Request arrives for /data{}NoYes
2Check cache for /data{}NoYes
3Cache miss, override res.send{}NoYes
4Call next middleware to fetch data{}NoYes
5Data fetched: 'Hello World'{}NoYes
6res.send('Hello World') called{'/data': 'Hello World'}YesNo
7Response sent with 'Hello World'{'/data': 'Hello World'}YesNo
8Next request arrives for /data{'/data': 'Hello World'}NoNo
9Check cache for /data{'/data': 'Hello World'}NoNo
10Cache hit, send cached response{'/data': 'Hello World'}YesNo
11Response sent with cached 'Hello World'{'/data': 'Hello World'}YesNo
💡 Execution stops after response is sent either from cache or fresh data.
Variable Tracker
VariableStartAfter Step 6After Step 10Final
cache{}{'/data': 'Hello World'}{'/data': 'Hello World'}{'/data': 'Hello World'}
res.sendResponseundefinedfunctionundefinedundefined
res.sendfunctionoverridden functionfunctionfunction
Key Moments - 3 Insights
Why do we override res.send inside the middleware?
We override res.send to capture the response body so we can store it in the cache before sending it to the client, as shown in step 6 of the execution_table.
What happens if the cache has the data?
If cache has data (cache hit), the middleware sends the cached response immediately without calling next(), as shown in steps 9 and 10.
Why do we call next() only on cache miss?
Calling next() passes control to the next middleware or handler to fetch fresh data only when cache misses, as shown in step 4.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the cache content after step 6?
Aundefined
B{}
C{"/data": "Hello World"}
D{"/data": null}
💡 Hint
Check the 'Cache State' column at step 6 in the execution_table.
At which step does the middleware send cached data without calling next()?
AStep 4
BStep 10
CStep 3
DStep 1
💡 Hint
Look for 'Cache hit' and 'Next Called' = No in the execution_table.
If we remove the override of res.send, what will happen on cache miss?
AResponse will not be cached
BCache will store empty data
CMiddleware will send cached data anyway
DNext middleware will not be called
💡 Hint
Refer to how caching happens at step 6 by overriding res.send.
Concept Snapshot
Cache Middleware Pattern in Express:
- Middleware checks if response for req.url is cached.
- If cached, sends cached response immediately.
- If not, overrides res.send to cache response body.
- Calls next() to fetch fresh data.
- Stores fresh response in cache before sending.
- Improves performance by avoiding repeated data fetch.
Full Transcript
This visual execution trace shows how cache middleware works in Express. When a request arrives, the middleware checks if the response is already cached for the request URL. If yes, it sends the cached response immediately without calling the next middleware. If no, it overrides the res.send method to capture the response body when the next middleware sends it. Then it calls next() to fetch fresh data. When the response is sent, the overridden res.send caches the response body before sending it to the client. This process speeds up repeated requests by serving cached data quickly. The variable tracker shows how the cache object updates after the first response. Key moments clarify why res.send is overridden and when next() is called. The quiz tests understanding of cache state and middleware flow.

Practice

(1/5)
1. What is the main purpose of cache middleware in an Express app?
easy
A. To handle user authentication
B. To store responses and speed up repeated requests
C. To parse incoming JSON data
D. To log all incoming requests

Solution

  1. Step 1: Understand cache middleware role

    Cache middleware stores responses temporarily to avoid repeating expensive operations.
  2. Step 2: Compare with other middleware roles

    Authentication, parsing, and logging serve different purposes unrelated to caching.
  3. Final Answer:

    To store responses and speed up repeated requests -> Option B
  4. Quick Check:

    Cache middleware = store responses [OK]
Hint: Cache middleware speeds up repeated requests by storing responses [OK]
Common Mistakes:
  • Confusing cache with authentication middleware
  • Thinking cache parses request bodies
  • Assuming cache logs requests
2. Which of the following is the correct way to define a simple cache middleware function in Express?
easy
A. function cache(req, res, next) { next(); res.send(cacheData); }
B. function cache(req, res) { res.send(cacheData); next(); }
C. function cache(req, res, next) { if (cacheData) res.send(cacheData); else next(); }
D. function cache(req, next, res) { if (cacheData) res.send(cacheData); else next(); }

Solution

  1. Step 1: Check middleware signature

    Express middleware functions take (req, res, next) in that order.
  2. Step 2: Verify control flow

    If cached data exists, send it; otherwise, call next() to continue processing.
  3. Final Answer:

    function cache(req, res, next) { if (cacheData) res.send(cacheData); else next(); } -> Option C
  4. Quick Check:

    Middleware signature and flow = function cache(req, res, next) { if (cacheData) res.send(cacheData); else next(); } [OK]
Hint: Middleware must have (req, res, next) and call next() if no cache [OK]
Common Mistakes:
  • Wrong parameter order in middleware function
  • Calling next() after sending response
  • Not calling next() when cache miss
3. Given this cache middleware snippet, what will be the output if cacheData is { message: 'Hello' }?
function cache(req, res, next) {
  if (cacheData) {
    res.json(cacheData);
  } else {
    next();
  }
}

app.get('/greet', cache, (req, res) => {
  res.json({ message: 'Hi there!' });
});
medium
A. {"message":"Hello"}
B. {"message":"Hi there!"}
C. Error: cacheData is undefined
D. No response sent

Solution

  1. Step 1: Check cacheData value

    cacheData is defined as { message: 'Hello' }, so the if condition is true.
  2. Step 2: Determine middleware behavior

    Since cacheData exists, middleware sends JSON response and does not call next().
  3. Final Answer:

    {"message":"Hello"} -> Option A
  4. Quick Check:

    cacheData present sends cached response [OK]
Hint: If cacheData exists, middleware sends it and skips next() [OK]
Common Mistakes:
  • Assuming next() runs even if cacheData exists
  • Confusing JSON string with object
  • Expecting original handler response
4. Identify the bug in this cache middleware code:
let cacheData;

function cache(req, res, next) {
  if (cacheData) {
    res.send(cacheData);
  }
  next();
}
medium
A. Middleware function missing req parameter
B. cacheData is not initialized
C. res.send should be res.json
D. next() is called even after sending a response

Solution

  1. Step 1: Analyze control flow

    If cacheData exists, res.send(cacheData) sends a response, but next() is still called afterward.
  2. Step 2: Understand Express behavior

    Calling next() after sending a response can cause errors or duplicate responses.
  3. Final Answer:

    next() is called even after sending a response -> Option D
  4. Quick Check:

    Calling next() after res.send causes errors [OK]
Hint: Do not call next() after sending a response [OK]
Common Mistakes:
  • Calling next() unconditionally after res.send
  • Ignoring middleware flow control
  • Assuming res.send and next() can run together
5. You want to implement cache middleware that stores responses for 10 seconds and then expires. Which approach correctly achieves this in Express?
hard
A. Store response in cacheData with a timestamp; clear cacheData if older than 10 seconds before sending
B. Use setTimeout to clear cacheData every 10 seconds regardless of requests
C. Send cached response only if cacheData exists, without checking time
D. Clear cacheData manually by restarting the server every 10 seconds

Solution

  1. Step 1: Understand cache expiration logic

    Cache should store data with a timestamp and check age before sending cached response.
  2. Step 2: Evaluate options

    Store response in cacheData with a timestamp; clear cacheData if older than 10 seconds before sending checks timestamp and clears stale cache before responding, ensuring fresh data.
  3. Final Answer:

    Store response in cacheData with a timestamp; clear cacheData if older than 10 seconds before sending -> Option A
  4. Quick Check:

    Cache expiration needs timestamp check [OK]
Hint: Use timestamps to expire cache, not just timers or manual clears [OK]
Common Mistakes:
  • Ignoring cache expiration timing
  • Clearing cache blindly without request context
  • Relying on server restart to clear cache
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard